在 python 异步中,有asyncio.Event,它允许您通知相邻任务有关某些事件:
import asyncio
event = asyncio.Event()
async def task1():
event.set()
async def task2():
while True:
await event.wait()
event.clear()
# do_some_work()
但是,对于相同的任务,您可以尝试简单地使用asyncio.Future:
import asyncio
event = asyncio.Future()
async def task1():
if not event.done():
event.set_result(True)
async def task2():
global event
while True:
await event
event = asyncio.Future() # clear
# do_some_work()
这些示例乍一看是等效的,并且工作方式相同。
但是,查看threading.Event 的实现,我看到其中使用了几个未来self._waiters = collections.deque(),并且为每个服务员创建了一个单独的未来。
然而,毕竟,你似乎可以多次等待同一个未来。所以,对于所有等待的人来说,一个未来就足够了。
或不?
简而言之,为什么asyncio.Event这么复杂?为什么它有双端队列和几个期货?asyncio.Event如果我使用一个单一的未来,我会遇到什么样的 rake ,就像在第二个例子中一样?
在我的实验中,我忘记了取消任务。如果您
task2多次从第二个示例运行,然后task2取消其中之一:...那么未来将进入该状态
cancelled,并且所有其他实例task2也将被取消,这很可能是不良行为。如果您为每个等待的人创建一个单独的未来,那么这些单独的未来可以毫无问题地取消,而不会干扰所有其他等待的未来。因此,在
asyncio.Eventand is neededself._waiters中,它为每个服务员存储了一个未来。但这只有在有几个等待时才有意义。如果总是有一个等待任务,那么显然这两个示例之间仍然没有区别。