首页 > 解决方案 > Python asyncio:在没有创建任务的情况下启动循环

问题描述

有人可以解释一下,如果我之前没有添加任何任务就开始循环,为什么我不能执行我的任务?(Python 3.7)

import asyncio
import threading    

def run_forever(loop):
    loop.run_forever()

async def f(x):
    print("%s executed" % x)

# init is called first
def init():
    print("init started")

    loop = asyncio.new_event_loop()

    # loop.create_task(f("a1")) # <--- first commented task

    thread = threading.Thread(target=run_forever, args=(loop,))
    thread.start()

    loop.create_task(f("a2")) # <--- this is not being executed

    print("init finished")

# loop.create_task(f("a1"))如果我对执行发表评论是:

init started
init finished

未注释的执行是:

init started
init finished
a1 executed
a2 executed

为什么这样?我想创建一个循环并在将来添加任务。

标签: python-3.xmultithreadingpython-asynciopython-3.7

解决方案


除非另有明确说明,否则 asyncio API不是线程安全的。这意味着loop.create_task()从运行事件循环的线程以外的线程调用将无法与循环正确同步。

要将任务从外部线程提交到事件循环,您需要调用asyncio.run_coroutine_threadsafe

asyncio.run_coroutine_threadsafe(f("a2"), loop)

这将唤醒循环以提醒它有新任务到达,它还会返回一个concurrent.futures.Future您可以用来获取协程结果的循环。


推荐阅读