Luc*_*iel 9 asynchronous future rust
我希望能够为一个“框架”睡我的未来,以便其他工作可以发生。这是这个想法的有效实现吗?
use std::future::Future;
use std::task::{Context, Poll};
use std::pin::Pin;
struct Yield {
yielded: bool,
}
impl Future for Yield {
type Output = ();
fn poll(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll<()> {
if self.yielded {
Poll::Ready(())
} else {
self.yielded = true;
// This is the part I'm concerned about
ctx.waker().wake_by_ref();
Poll::Pending
}
}
}
Run Code Online (Sandbox Code Playgroud)
具体来说,我担心的是,wake_by_ref如果调用是在轮询返回之前进行的,则上下文不会“注意到”该调用Pending。poll以这种方式执行时,接口契约是否保证此任务会立即重新轮询?
TL;DR:您的代码有效。
根据唤醒者的合同,它必须再次轮询你的未来。Future::poll否则,调用和未来实际执行某些工作的对应调用之间可能会出现竞争条件。
让我们看一个例子:
impl Future for Foo {
type Output = ();
fn poll(self: Pin<&mut Self>, ctx: &mut Context) -> Poll<()> {
let result = communicate_with_worker(ctx); // returns false
// <-- Time point (1)
return match result {
true => Poll::Pending,
false => Poll::Ready(()),
};
}
}
Run Code Online (Sandbox Code Playgroud)
在时间点 (1),future 已确定它尚未准备好,但轮询线程可能在此暂停,并且工作线程已被调度并完成其工作。
然后工作线程将调用唤醒器并请求再次轮询 future。如果唤醒器决定不再轮询未来,因为它现在正在轮询未来,那么唤醒器将永远不会再次收到唤醒请求。
这意味着唤醒器可以丢弃调用之前发出的唤醒请求
poll,但不允许丢弃在未来poll调用期间发出的唤醒请求。
我唯一的问题是:您为什么要重新安排一帧的轮询?
由于您的实际工作必须在单独的线程中完成(而不是在内部fn poll),因此重新安排轮询没有任何意义。
| 归档时间: |
|
| 查看次数: |
669 次 |
| 最近记录: |