asyncio:用于同步的事件与未来
asyncio: Event vs Future for synchronization
我正在浏览一些 asyncio
网络资源和实施,这在我脑海中提出了一个问题。
要在等待数据从套接字到达时创建一个非阻塞 I/O,asyncio.StreamReader.read()
在其末尾调用 _wait_for_data
方法 creates an empty Future
并等待它。
在 新数据到达时调用的 _wakeup_waiter
方法中,该未来被设置为 finished(这允许最终等待它) 到流(feed_data
方法)。
完全有道理。
我的问题是:
为什么不使用 asyncio.Event
? 我觉得 Event 正是为这些目的而设计的。事实上,您不必在每次 _wait_for_data
调用时都创建一个新的 Future,而是会在 class 中初始化单个事件,并在其生命周期内简单地切换其值。它还具有特定的 .wait()
方法来等待其值变为 True(当新数据从套接字到达时)。
任何人都可以详细说明这两种方法之间是否存在实际差异?还是只是随意选择的方法?
虽然通常您可以将 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
,您将无法实现此目的。
Future 是低级原语。
它很强大,但用户代码通常不需要它。
就像 Linux 有 futex 但用户代码使用高级对象,如锁和递归锁。
我正在浏览一些 asyncio
网络资源和实施,这在我脑海中提出了一个问题。
要在等待数据从套接字到达时创建一个非阻塞 I/O,asyncio.StreamReader.read()
在其末尾调用 _wait_for_data
方法 creates an empty Future
并等待它。
在 新数据到达时调用的 _wakeup_waiter
方法中,该未来被设置为 finished(这允许最终等待它) 到流(feed_data
方法)。
完全有道理。
我的问题是:
为什么不使用 asyncio.Event
? 我觉得 Event 正是为这些目的而设计的。事实上,您不必在每次 _wait_for_data
调用时都创建一个新的 Future,而是会在 class 中初始化单个事件,并在其生命周期内简单地切换其值。它还具有特定的 .wait()
方法来等待其值变为 True(当新数据从套接字到达时)。
任何人都可以详细说明这两种方法之间是否存在实际差异?还是只是随意选择的方法?
虽然通常您可以将 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
,您将无法实现此目的。
Future 是低级原语。 它很强大,但用户代码通常不需要它。 就像 Linux 有 futex 但用户代码使用高级对象,如锁和递归锁。