【问题标题】:How to (gevent) spawn tasks without waiting for it to join如何(gevent)生成任务而不等待它加入
【发布时间】:2017-11-20 02:10:03
【问题描述】:

我已经为我的问题编写了一个示例代码。我正在生成一个随机字符串和一个随机播放函数,它会为消息添加延迟,因此它会以不同的顺序出现。

但是,计划任务只有在我最后有joinall 时才会执行。有没有办法在动态调度新的生成任务的同时执行调度和任务。当我一直按 Enter 键时,它会安排一个新任务,但在达到我设置的随机条件之前它不会执行。但是,如果我将 join/joinall 放在附加之后,它会阻塞。这是否可能与 gevent 或其他库可以与任何其他异步 I/O 或非阻塞库一起完成,还是我必须求助于多线程。

#!/usr/bin/python
import random 
import string
from gevent import sleep, spawn, joinall

def random_string():
    digits = "".join( [random.choice(string.digits) for i in xrange(8)] )
    chars = "".join( [random.choice(string.letters) for i in xrange(10)] )
    return chars

def delay_message(message, delay):
    sleep(delay)
    print("Shuffled message: {} and time: {}". format(message, delay))

def main():
    while True:
        s = raw_input("Please continue pressing enter, messages will appear when they are ready")
        if s == "":
            delay = random.randint(0, 10)
            string = random_string()
            print("Message: {} and time: {}". format(string, delay))
            tasks = []
            tasks.append(spawn(delay_message, string, delay))

            if (random.randint(0,10) == 5): # random condition in breaking
                joinall(tasks, raise_error=True)
                break
        else:
            print("Exiting")
            break

if __name__ == "__main__":
    main()

【问题讨论】:

  • raw_input 是一个阻塞操作系统调用。 gevent 是合作的,所以当主greenlet 卡在raw_input 没有其他greenlet 可以运行。这是您有问题的实际代码,还是您将其简化为包含raw_input
  • @JasonMadden 不是raw_input,而是sock.recv(),而不是在delay_message 打印,我会sendall()。这还会造成问题吗?
  • 除非您很早就对系统进行了猴子补丁,或者专门导入和使用 gevent 的套接字类,否则这些仍然会阻塞会导致此问题的调用。

标签: python scheduled-tasks scheduler gevent


【解决方案1】:

具体来说,无论你加入与否,工作都会完成,你只需要在你需要确保工作完成后再加入以确保并发,你可以使用很多方法来获得你的状态继续进行(队列、共享变量、回调、委托方法),因为您使用的是 greenlet,所以您甚至不需要锁定像添加数字这样的原子操作,因为它们发生在同一个线程上。

【讨论】:

    【解决方案2】:

    我找到了解决方案:使用 ThreadPool 例如tasks = ThreadPool(25) 分配在循环外并删除 tasks=[]joinall()

    另外,在break前的while循环中的随机条件中添加from gevent import wait然后添加wait(),这样现有的任务就可以在程序退出前完成

    【讨论】:

    • 所以如果你用猴子补丁,正常的事情会变成 gevent 产生事件,比如睡眠和 io 读取......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多