更新时间:2022-05-31 16:34:36
在Event_loop运行后向其添加任务是标准做法,为什么空案例会成为问题?
因为您应该从运行事件循环的线程添加任务。一般而言,不应混用线程和异步,除非通过为此目的而设计的API,如loop.run_in_executor
。
如果您了解这一点,并且仍然有充分的理由从单独的线程添加任务,请使用asyncio.run_coroutine_threadsafe
。将loop.create_task(bar(...))
更改为:
asyncio.run_coroutine_threadsafe(bar("in loop"), loop=loop)
run_coroutine_threadsafe
以线程安全的方式访问事件循环,并确保事件循环唤醒以通知新任务,即使它与其他任务无关并且只是在等待IO/超时。
bar
碰巧是一个无限协程,它使事件循环每秒唤醒一次。一旦事件循环出于任何原因被唤醒,它就会执行所有可运行的任务,而不管是哪个线程添加了这些任务。但是,依赖于此确实不是一个好主意,因为loop.create_task
不是线程安全的,因此如果它与正在运行的事件循环并行执行,则可能会出现任意数量的争用条件。