异步队列在与后台线程一起使用时会挂起

4
似乎只有相同的线程才能推送 asyncio.Queue,例如:
import asyncio
from threading import Thread
import time

q = asyncio.Queue()

def produce():
    for i in range(100):
        q.put_nowait(i)
        time.sleep(0.1)

async def consume():
    while True:
        i = await q.get()
        print('consumed', i)

Thread(target=produce).start()
asyncio.get_event_loop().run_until_complete(consume())

仅打印

consumed 0

然后程序就无响应了,我错过了什么吗?

1个回答

6

直接从另一个线程调用asyncio方法是不可行的。

可以使用loop.call_soon_threadsafe:

loop.call_soon_threadsafe(q.put_nowait, i)

或者 asyncio.run_coroutine_threadsafe:
future = asyncio.run_coroutine_threadsafe(q.put(i), loop)

其中 loop 是由 asyncio.get_event_loop() 在你的主线程中返回的循环。


你的建议并没有取得任何成功(程序仍然像之前一样卡住),能否请您提供一个简单的例子来说明? - Jonas Byström
2
啊。需要使用与主线程相同的循环,而get_event_loop并不适用于此。 - Jonas Byström

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接