python asyncio queue_Python asyncio - 使用asyncio.Event()阻止消费者

我有一个程序有一个 生产环境 者和两个 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绘制解决方案,第二个绘图结果) .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个关于使用 `asyncio.run_coroutine_threadsafe()` 进行消息队列入队出队的示例: ```python import asyncio import queue # 创建一个消息队列 message_queue = queue.Queue() # 定义一个协程,用于从队列中获取消息 async def consume_message(): while True: # 从队列中获取消息 message = message_queue.get() # 处理消息 print("Consumed message:", message) # 定义一个函数,用于将消息发送到队列中 def send_message(message): # 将消息推入队列 message_queue.put(message) # 在事件循环中异步调用 consume_message() 协程 asyncio.run_coroutine_threadsafe(consume_message(), loop) # 创建一个事件循环 loop = asyncio.get_event_loop() # 启动消费者协程 asyncio.ensure_future(consume_message()) # 发送一些消息 send_message("Hello, world!") send_message("How are you?") send_message("Goodbye!") # 运行事件循环 loop.run_forever() ``` 在上面的示例中,我们首先创建了一个简单的消息队列 `message_queue`。然后,我们定义了一个协程 `consume_message()`,它会从队列中获取消息并进行处理。 接下来,我们定义了一个函数 `send_message()`,用于将消息发送到队列中。在这个函数中,我们首先将消息推入队列中,然后使用 `asyncio.run_coroutine_threadsafe()` 方法在事件循环中异步调用 `consume_message()` 协程。 最后,我们创建一个事件循环,并使用 `asyncio.ensure_future()` 启动消费者协程。然后,我们调用 `send_message()` 函数发送一些消息,并运行事件循环。在事件循环中,我们将一直等待新的消息,并使用 `consume_message()` 协程进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值