pub trait Future {
type Output;
// Required method
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
Expand description
Required Associated Types§
Required Methods§
sourcefn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>
尝试将 future 解析为最终值,如果该值尚不可用,请注册当前任务以进行唤醒。
返回值
该函数返回:
Poll::Pending
如果 future 还没有准备好Poll::Ready(val)
与此 future 的结果val
如果它成功完成。
future 完成后,客户端不应再次对其进行 poll
。
当 future 尚未准备好时,poll
返回 Poll::Pending
并存储从当前 Context
复制的 Waker
的副本。
future 可以取得进展后,将唤醒该 Waker
。
例如,等待套接字可读的 future 将在 Waker
上调用 .clone()
并将其存储。
当信号到达其他地方指示套接字可读时,将调用 Waker::wake
,并且唤醒套接字 future 的任务。
一旦任务被唤醒,它应该尝试再次 poll
future,这可能会或可能不会产生最终值。
请注意,在多次调用 poll
时,应仅计划将 Context
中传递给最新调用的 Waker
接收唤醒。
运行时特征
单独的 Futures 是惰性的; 必须对它们进行主动轮询以取得进展,这意味着每次唤醒当前任务时,它都应主动重新轮询以等待仍对其感兴趣的 futures。
poll
函数不会在紧密循环中重复调用 - 而是仅在 future 指示已准备好进行调用时 (通过调用 wake()
) 才应调用它。
如果您熟悉 Unix 上的 poll(2)
或 select(2)
系统调用,则值得注意的是 futures 通常不会遭受与 “所有唤醒都必须轮询所有事件” 相同的问题; 他们更像 epoll(4)
。
poll
的实现应努力迅速返回,并且不应阻塞。快速返回可防止不必要地阻塞线程或事件循环。
如果提前得知对 poll
的调用可能要花一点时间,则应将工作卸载到线程池 (或类似的线程) 中,以确保 poll
可以快速返回。
Panics
future 完成后 (从 poll
返回 Ready
),再次调用其 poll
方法可能会导致 panic 永久阻塞或引起其他类型的问题。Future
trait 对这种调用的效果没有任何要求。
但是,由于 poll
方法未标记为 unsafe
,因此适用 Rust 的通常规则:调用绝不能引起未定义的行为 (内存损坏,unsafe
函数的错误使用等),而与 future 的状态无关。