我写了一个问题的示例代码。输入消息被分成固定的块并使用有意的随机延迟进行混合。但是,sleep()
正在阻止,不会运行下一个任务。这可能在一个线程上还是我必须求助于多线程?
from random import randint
from time import sleep
def delay_message(split_message, delay):
#sleep(delay) #this blocks
print("Shuffled message: {} and time: {}". format(split_message, delay))
def main():
message = raw_input('Input: ')
#padding
difference = len(message) % 5
message=message.ljust(len(message)+5-difference, "0")
for i in range(0, len(message), 5):
delay = randint(0, 5)
split_message = message[i:i+5]
delay_message(split_message, delay)
if __name__ == "__main__":
main()
答案 0 :(得分:1)
sleep
确实会阻止其正在运行的线程。
可以使用gevent
等库来使其无阻塞。 Gevent还可以修补time.sleep
并使其无阻塞,并且还有自己的非阻塞睡眠。它还可以修补整个python标准库,使其无阻塞 - 套接字,时间,线程等,请参阅documentation。
上面的例子可以与gevent合作,如下:
from random import randint
from gevent import sleep, spawn, joinall
def delay_message(split_message, delay):
# Gevent's sleep yields the event loop for
# duration of delay rather than blocking the running thread
sleep(delay)
print("Shuffled message: {} and time: {}". format(split_message, delay))
def main():
message = raw_input('Input: ')
#padding
difference = len(message) % 5
message=message.ljust(len(message)+5-difference, "0")
greenlets = []
# This will create len(message)/5 number of greenlets,
# which corresponds to the concurrency level.
# Greenlets all run under one thread so there is no CPU
# overhead here.
for i in range(0, len(message), 5):
delay = randint(0, 5)
split_message = message[i:i+5]
greenlets.append(spawn(delay_message, split_message, delay))
# Wait for all greenlets to complete, raise any exceptions
joinall(greenlets, raise_error=True)
if __name__ == "__main__":
main()
约束是CPU绑定的任务不能在greenlet中运行,因为它们会阻塞事件循环和所有其他greenlet。
只要在greenlet中运行的是I / O绑定,比如在套接字或生成器中传递消息,其他greenlet等,greenlets是合适的。对于CPU绑定任务,请使用本机线程或多个进程。
还有其他选择,例如asyncio
(仅限Py3)。 Gevent与Py2和3兼容,具有非常高的性能,以本机代码扩展为后盾。