我有一个程序有一个 生产环境 者和两个 slow 消费者,我想用协同程序重写它,以便每个消费者将处理为它生成的 only last value (即跳过处理旧的生成的新值)(我使用了线程和 threading.Queue() 但是在 put() 上有块,导致队列大部分时间都是满的 .
阅读answer to this question后,我决定使用 asyncio.Event 和 asyncio.Queue . 我写了这个原型程序:
import asyncio
async def l(event, q):
h = 1
while True:
# ready
event.set()
# get value to process
a = await q.get()
# process it
print(a * h)
h *= 2
async def m(event, q):
i = 1
while True:
# pass element to consumer, when it's ready
if event.is_set():
await q.put(i)
event.clear()
# produce value
i += 1
el = asyncio.get_event_loop()
ev = asyncio.Event()
qu = asyncio.Queue(2)
tasks = [
asyncio.ensure_future(l(ev, qu)),
asyncio.ensure_future(m(ev, qu))
]
el.run_until_complete(asyncio.gather(*tasks))
el.close()
而且我注意到 q.get() 行上的 l coroutine块并且没有打印任何内容 .
在两者中添加 asyncio.sleep() 之后,它的工作方式正如我所期望的那样(我得到 1,11,21,... ):
import asyncio
import time
async def l(event, q):
h = 1
a = 1
event.set()
while True:
# await asyncio.sleep(1)
a = await q.get()
# process it
await asyncio.sleep(1)
print(a * h)
event.set()
async def m(event, q):
i = 1
while True:
# pass element to consumer, when it's ready
if event.is_set():
await q.put(i)
event.clear()
await asyncio.sleep(0.1)
# produce value
i += 1
el = asyncio.get_event_loop()
ev = asyncio.Event()
qu = asyncio.Queue(2)
tasks = [
asyncio.ensure_future(l(ev, qu)),
asyncio.ensure_future(m(ev, qu))
]
el.run_until_complete(asyncio.gather(*tasks))
el.close()
......但我正在寻找没有它的解决方案 .
为什么会这样?我该如何解决?我想我不能从 m 调用 await l() ,因为它们都有状态(原始程序中第一个用PyGame绘制解决方案,第二个绘图结果) .