asyncio事件循环可以在后台运行而不挂起Python解释器吗?

时间:2014-10-09 05:03:09

标签: python concurrency python-asyncio

asyncio的文档提供了两个如何打印" Hello World"每两秒钟: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio-hello-world-callback https://docs.python.org/3/library/asyncio-task.html#asyncio-hello-world-coroutine

我可以从解释器运行那些,但是如果我这样做,我将无法访问解释器。可以在后台运行asyncio事件循环,以便我可以在解释器上继续输入命令吗?

2 个答案:

答案 0 :(得分:39)

您可以在后台线程中运行事件循环:

>>> import asyncio
>>> 
>>> @asyncio.coroutine
... def greet_every_two_seconds():
...     while True:
...         print('Hello World')
...         yield from asyncio.sleep(2)
... 
>>> def loop_in_thread(loop):
...     asyncio.set_event_loop(loop)
...     loop.run_until_complete(greet_every_two_seconds())
... 
>>> 
>>> loop = asyncio.get_event_loop()
>>> import threading
>>> t = threading.Thread(target=loop_in_thread, args=(loop,))
>>> t.start()
Hello World
>>> 
>>> Hello World

请注意,您必须asyncio.set_event_loop上致电loop,否则您会收到错误消息,指出当前线程没有发生任何事件循环。

如果您想与主线程中的事件循环进行互动,则需要坚持loop.call_soon_threadsafe次来电。

虽然这种方法可以在解释器中进行实验,但在实际程序中,您可能希望所有代码在事件循环中运行,而不是引入线程。

答案 1 :(得分:1)

使用Python 3.8,您可以使用新的asyncio REPL。

$ python -m asyncio
>>> async def greet_every_two_seconds():
...     while True:
...         print('Hello World')
...         await from asyncio.sleep(2)
...
>>> # run in main thread (Ctrl+C to cancel)
>>> await greet_every_two_seconds()
...
>>> # run in background
>>> asyncio.create_task(greet_every_two_seconds())