如何异步非阻塞调度python中触发的任务或事件?
How to asynchronously non-block schedule task or event triggered in python?
我已经写了我的问题的示例代码。输入消息被分成固定的块,并使用有意的随机延迟进行混合。但是,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()
sleep
确实会阻塞其 运行ning 线程。
可以通过使用 gevent
. Gevent can also patch time.sleep
and make it non-blocking and also has its own non-blocking sleep. It can also patch the entire python standard library to make it non-blocking - socket, time, threading etc, see 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 绑定任务不能 运行 在 greenlets 中,因为它们会阻塞事件循环和所有其他 greenlets。
只要 greenlet 中的 运行 是 I/O 绑定的,例如在套接字或生成器中传递消息,其他 greenlets 等,greenlets 都是合适的。对于 CPU 绑定任务,使用本机线程或多进程。
还有其他选择,例如 asyncio
(仅限 Py3)。 Gevent 与 Py2 和 3 兼容,具有非常高的性能,由本机代码扩展支持。
我已经写了我的问题的示例代码。输入消息被分成固定的块,并使用有意的随机延迟进行混合。但是,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()
sleep
确实会阻塞其 运行ning 线程。
可以通过使用 gevent
. Gevent can also patch time.sleep
and make it non-blocking and also has its own non-blocking sleep. It can also patch the entire python standard library to make it non-blocking - socket, time, threading etc, see 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 绑定任务不能 运行 在 greenlets 中,因为它们会阻塞事件循环和所有其他 greenlets。
只要 greenlet 中的 运行 是 I/O 绑定的,例如在套接字或生成器中传递消息,其他 greenlets 等,greenlets 都是合适的。对于 CPU 绑定任务,使用本机线程或多进程。
还有其他选择,例如 asyncio
(仅限 Py3)。 Gevent 与 Py2 和 3 兼容,具有非常高的性能,由本机代码扩展支持。