【发布时间】: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