[英]Asyncio How do you use run_forever?
我想做的事:
我的理解是由于#3,需要在循环上调用run_forever()
以确保任务在循环上得到调度。 但是,如果我调用run_forever()
那么我的主线程就会阻塞,永远不会终止。
我试过的
生成一个线程,在循环中传递,然后在该线程中调用run_forever
。 这意味着尽管我的单元测试从未完成。 要点:
def __start_background_loop(loop):
def run_forever(loop):
loop.run_forever()
# because run_forever() will block the current thread, we spawn
# a subthread to issue that call in.
thread = Thread(target=run_forever, args=(loop,))
thread.start()
def __end_background_loop(loop):
for task in Task.all_tasks(loop):
task.cancel()
loop.stop()
有两种可能的方法:您可以在主线程或后台线程中运行事件循环。 如果在主线程中运行它,则需要在程序初始化的最后一步中运行run_forever
(或run_until_complete(main())
或同等功能)。 在那种情况下,主线程将“阻塞”,但这是可以的,因为它的事件循环将继续运行并响应外部事件,从而允许程序运行。 分派协程和回调的事件循环的单个“阻塞”调用是设计异步运行的方式。
在不切实际的情况下,例如包含大量同步代码的程序,或者已经在多个线程之间进行通信的程序,通常最好创建一个专用线程并在其中运行事件循环。 在那种情况下,除了要调用loop.call_soon_threadsafe()
和asyncio.run_coroutine_threadsafe()
之外,您必须非常小心不要与事件循环通信。 例如, __end_background_loop
必须通过调用loop.call_soon_threadsafe(__end_background_loop)
因为它的任务和事件循环互动。 这适用于与事件循环的所有交互-例如,不允许从另一个线程调用loop.stop()
,必须将其拼写为loop.call_soon_threadsafe(loop.stop)
。 当然,从asyncio回调和协程调用循环函数很好,因为它们将始终在与事件循环运行所在的线程中运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.