我正在浏览一些asyncio
网络和实施的来源,在我脑海中提出了一个问题。
要在等待数据从套接字到达时创建非阻塞I / O,asyncio.StreamReader.read()
在其末尾调用_wait_for_data
creates an empty Future
并等待它的方法。
当新数据到达时,_wakeup_waiter
方法中的已完成(允许最终等待) (feed_data
方法)。
这完全合情合理。
我的问题是:
为什么不使用asyncio.Event
?我觉得Event就是为了这些目的而设计的。实际上,您不必在每个_wait_for_data
调用上创建一个新的Future,而是在一个类中初始化一个Event,并在其生命周期内简单地切换它的值。它还具有特定的.wait()
方法,用于等待其值变为True(当新数据从套接字到达时)。
任何人都可以详细说明两种方法之间是否存在实际差异?或者它只是一种随意选择的方法?
答案 0 :(得分:3)
虽然通常可以将Future
替换为Event
但如果您不关心将来会填充数据,我认为在这种情况下不是这样。
代码self._waiter
不仅用于表示唤醒事件,还用于表示发生的indicate exception。 set_exception
到Future
表示在将来等待代码的代码中会引发此异常:
#
waiter.set_exception(exc) # Exception set here...
#
self._waiter = self._loop.create_future()
try:
yield from self._waiter # ... will be raised here and propagated to outer code
finally:
self._waiter = None
如果您将self._waiter
更改为Event
,则无法实现此目的。
答案 1 :(得分:0)
未来是低级原始。 它功能强大,但用户代码通常不需要它。 像Linux有futex,但用户代码使用高级对象,如锁和递归锁。