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

问题描述 投票:0回答:3

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

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

python concurrency python-asyncio
3个回答
63
投票

编辑:

如果使用 Python 3.8 或更高版本,则应使用

asyncio
repl,如 zeronone 的回答中所述。如果使用 3.7 或更低版本,您可以使用这个答案。


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

>>> 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
调用。

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


42
投票

使用 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())

0
投票

@raisyn

ipython
开始,这是有效的:

import asyncio
from traitlets.config.application import Application

async def greet_every_two_seconds():
    while True:
        print('Hello World')
        await asyncio.sleep(2)
        
# Create coroutine
coro = greet_every_two_seconds()

# Create and get an adequate asyncio event loop
Application.instance().shell.enable_gui('asyncio')
loop = asyncio.get_event_loop()

loop.create_task(coro)

© www.soinside.com 2019 - 2024. All rights reserved.