gpt4 book ai didi

python - 将任务安排为从同步代码运行事件循环

转载 作者:太空宇宙 更新时间:2023-11-03 14:11:16 25 4
gpt4 key购买 nike

考虑这个程序,其中主循环和停止它的协程实际上是由我正在使用的库实现的。

import asyncio
import signal

running = True

async def stop():
global running
print("setting false")
running = False
await asyncio.sleep(3)
print("reached end")

async def mainloop():
while running:
print("loop")
await asyncio.sleep(1)

def handle_signal():
loop.create_task(stop())

loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, handle_signal)
loop.run_until_complete(mainloop())
loop.close()

当程序收到信号时,我需要调用停止协程来停止主循环。尽管在使用 asyncio.BaseEventLoop.create_task 调度停止协程时,它首先停止主循环,从而停止事件循环,并且停止协程无法完成:

$ ./test.py 
loop
loop
loop
^Csetting false
Task was destroyed but it is pending!
task: <Task pending coro=<stop() done, defined at ./test.py:7> wait_for=<Future pending cb=[Task._wakeup()]>>

如何将协程添加到正在运行的事件循环中,同时使事件循环等待直到完成?

最佳答案

正如您所发现的,问题在于事件循环仅等待 mainloop() 完成,而使 stop() 挂起,这 asyncio 正确地提示。

如果handle_signal和顶级代码在您的控制之下,您可以轻松地将循环直到mainloop完成替换为循环直到自定义协程完成。该协程将调用 mainloop,然后等待清理代码完成:

# ... omitted definition of mainloop() and stop()

# list of tasks that must be waited for before we can actually exit
_cleanup = []

async def run():
await mainloop()
# wait for all _cleanup tasks to finish
await asyncio.wait(_cleanup)

def handle_signal():
# schedule stop() to run, and also add it to the list of
# tasks run() must wait for before it is done
_cleanup.append(loop.create_task(stop()))

loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, handle_signal)
loop.run_until_complete(run())
loop.close()

另一个选项,不需要新的 run() 协程(但仍然需要修改的 handle_signal),是发出第二个 run_until_complete( ) mainloop 完成后:

# handle_signal and _cleanup defined as above

loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, handle_signal)
loop.run_until_complete(mainloop())
if _cleanup:
loop.run_until_complete(asyncio.wait(_cleanup))
loop.close()

关于python - 将任务安排为从同步代码运行事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48479346/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com