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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26270681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 00:18:23  来源:igfitidea点击:

Can an asyncio event loop run in the background without suspending the Python interpreter?

pythonconcurrencypython-asyncio

提问by Jeffrey Benjamin Brown

The documentation for asyncio gives two examples for how to print "Hello World" every two seconds: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio-hello-world-callbackhttps://docs.python.org/3/library/asyncio-task.html#asyncio-hello-world-coroutine

asyncio 的文档给出了如何每两秒打印一次“Hello World”的两个示例:https://docs.python.org/3/library/asyncio-eventloop.html#asyncio-hello-world-callback https://docs.python.org/3/library/asyncio-eventloop.html#asyncio-hello-world-callback docs.python.org/3/library/asyncio-task.html#asyncio-hello-world-coroutine

I can run those from the interpreter, but if I do I lose access to the interpreter. Can an asyncio event loop be run in the background, so that I can keep typing commands at the interpreter?

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

回答by dano

Edit:

编辑:

If using Python 3.8 or above, you should use the asynciorepl, as explained in zeronone's answer. If using 3.7 or lower, you can use this answer.

如果使用 Python 3.8 或更高版本,则应使用asynciorepl,如zeronone 的回答中所述。如果使用 3.7 或更低版本,则可以使用此答案。



You can run the event loop inside a background thread:

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

>>> 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

Note that you mustcall asyncio.set_event_loopon the loop, otherwise you'll get an error saying that the current thread doesn't have an event loop.

请注意,您必须调用asyncio.set_event_looploop,否则你会得到一个错误,指出当前线程没有一个事件循环。

If you want to interact with the event loop from the main thread, you'll need to stick to loop.call_soon_threadsafecalls.

如果你想从主线程与事件循环交互,你需要坚持loop.call_soon_threadsafe调用。

While this kind of thing is an ok way to experiment in the interpreter, in actual programs, you'll probably want allyour code running inside the event loop, rather than introducing threads.

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

回答by zeronone

With Python 3.8, you can use the new asyncio REPL.

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

$ python -m asyncio
>>> async def greet_every_two_seconds():
...     while True:
...         print('Hello World')
...         await 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())