如何(gevent)在不等待它加入的情况下产生任务
我写了一个我的问题的示例代码。我正在生成一个随机字符串和一个shuffle函数,它为消息添加了一个延迟,所以它以不同的顺序出现。如何(gevent)在不等待它加入的情况下产生任务
但是,计划任务只有在末尾有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()
我发现了一个解决方案:使用ThreadPool例如tasks = ThreadPool(25)
分配外循环并删除tasks=[]
和joinall()
此外,添加from gevent import wait
然后在休息前while循环随机条件添加wait()
,从而退出程序之前,现有的任务可以完成
所以如果你monkeypatch,正常的事情变成gevent屈服事件,如睡眠和io阅读...... –
无论您是否加入,您都可以完成工作,您只需在需要确保工作完成之前加入以确保并发性,您可以使用大量方法获取状态(队列,共享变量,回调,委托方法),因为你使用的是greenlet,你甚至不需要像添加数字那样锁定原子操作,因为它们正在发生同一个线程。
'raw_input'是一个* blocking *操作系统调用。 gevent是合作的,所以当主greenlet卡在'raw_input'中时*没有其他greenlet可以运行*。这是你的实际代码,你有问题,或者你简化它包含'raw_input'? –
@JasonMadden代替'raw_input',它会是'sock.recv()',而不是在delay_message处打印,我会'sendall()'。这仍然会造成问题吗? – Anderson
除非你很早就对系统进行了猴子修补,或者是专门导入和使用gevent的套接字类,是的,那些仍然会阻塞会导致这个问题的调用。 –