我有以下代码:
import asyncio
import threading
import time
q = asyncio.Queue()
async def ping():
while True:
await asyncio.sleep(10)
print("ping")
async def rcv():
while True:
item = await q.get()
print("got item")
async def run():
tasks = [asyncio.ensure_future(ping()), asyncio.ensure_future(rcv())]
await asyncio.wait(tasks, return_when="FIRST_EXCEPTION")
loop = asyncio.get_event_loop()
def run_loop():
asyncio.set_event_loop(loop)
loop.run_until_complete(run())
threading.Thread(target=run_loop).start()
while True:
time.sleep(2)
q.put_nowait("item")
print("item added")
我希望每2秒(每个时间项都添加到队列中),我将看到输出:
item added
sleeping 2 seconds
got item
每隔10秒我还会看到ping
。
但是,这是我得到的(重复)输出:
sleeping 2 seconds
item added
sleeping 2 seconds
item added
sleeping 2 seconds
item added
sleeping 2 seconds
item added
sleeping 2 seconds
got item
got item
got item
got item
ping
item added
sleeping 2 seconds
...
似乎item = await q.get()
部分也从asyncio.sleep(10)
函数中等待ping
。
我想念什么?以及如何修复代码以便获得预期的输出?
谢谢!
答案 0 :(得分:2)
我想念什么?以及如何修复代码以便获得预期的输出?
由于您是在单独的线程中运行事件循环,因此需要将q.put_nowait("item")
更改为:
loop.call_soon_threadsafe(q.put_nowait, "item")
原因是异步代码(故意)不是线程安全的,因此使用put_nowait
不会通知事件循环新项目已入队。