是否确保asyncio.Event服务员收到设置事件的通知

协程是否正在等待asyncio.Event设置为保证每次设置事件时都会得到通知?

Event.set()和Event.clear()都不是可等待的。因此,可以设置和清除事件,而无需将控制返回到循环。因此,我猜调用set()和clear()不会将事件通知侍者。我发现确保通知服务员的唯一方法是添加asycnio.sleep(0),以将控件强制返回到set()和clear()之间的循环。但这对我来说看起来很丑。

这里是一个例子:

NUM_EVENTS = 1000
NUM_WAITERS = 1000

import asyncio

async def waiter(event,id):
    print('waiting for it ...')
    for i in range(NUM_EVENTS):
        await event.wait()
        await asyncio.sleep(0)  # might be dropped by affects order
        print(f'... {id} got {i}')

async def main():
    # Create an Event object.
    event = asyncio.Event()

    # Spawn a Task to wait until 'event' is set.
    waiter_tasks = []
    for i in range(NUM_WAITERS):
        waiter_tasks.append(asyncio.create_task(waiter(event,i)))

    # Sleep for 1 second and set the event.
    await asyncio.sleep(1)
    for i in range(NUM_EVENTS):
        event.set()
        await asyncio.sleep(0)  # leaving this out will result in the waiters only receiving the event once
        event.clear()

    # Wait until the waiter task is finished.
    await asyncio.wait(waiter_tasks)

if __name__ == '__main__':
    asyncio.run(main())

在第31行上省略asyncio.sleep(0)会使服务员仅接收一次(而不是1000次)事件。

但是如何干净地做到这一点?

zhuhui34555 回答:是否确保asyncio.Event服务员收到设置事件的通知

  

协程是否正在等待asyncio.Event设置为保证每次设置事件时都会得到通知?

服务员只能保证注意到set()在等待时发生,即使紧随其后的是clear()。无法保证将状态从false更改为true时会被唤醒。

这种更有力的保证将需要在对象上增加一个计数器,而不再是简单的布尔“事件”。它也将与threading.Event不兼容,后者不提供它。

  

但是如何干净地做到这一点?

干净的方法是让Event仅标记“已发生某事”,并存储已发生的元信息 (如果需要的话,还包括计数器)。在旁边。这样,事件对象就可以达到一个目的:向服务员发信号说他们一直在等待的事件已经发生,他们可以自己循环必要的次数。

如果服务员需要对set()做出立即的反应,那么等待asyncio.sleep(0)是解决问题的方法,但是在异步方式中,这有点设计上的味道。不过,在不了解更多代码的情况下,很难说出解决方法。

本文链接:https://www.f2er.com/3156292.html

大家都在问