【问题标题】:Python asyncio: starting a loop without created taskPython asyncio:在没有创建任务的情况下启动循环
【发布时间】:2019-03-15 22:24:27
【问题描述】:

如果我在没有任何添加任务的情况下启动循环,有人可以解释一下为什么我不能执行我的任务吗? (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.x multithreading python-asyncio python-3.7


    【解决方案1】:

    除非另有明确说明,否则异步 API is not thread-safe。这意味着从运行事件循环的线程以外的线程调用loop.create_task() 将无法与循环正确同步。

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

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

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

    【讨论】:

    • 非常感谢!我明白了。
    猜你喜欢
    • 1970-01-01
    • 2013-04-10
    • 2019-12-06
    • 2015-03-07
    • 1970-01-01
    • 2020-06-21
    • 2020-09-25
    • 2019-02-27
    • 2018-08-21
    相关资源
    最近更新 更多