asynchronous - 在轮询时唤醒 Rust future 是否有效?

标签 asynchronous rust future

我希望能够让我的 future 睡一个“框架”,以便其他工作可以发生。这是这个想法的有效实现吗?

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
        }
    }
}

具体来说,我担心的是上下文不会“注意到” wake_by_ref如果在投票返回 Pending 之前进行,则调用. poll的接口(interface)契约是否以这种方式执行时,是否保证该任务会立即重新轮询?

最佳答案

TL;DR:您的代码是有效的。

根据唤醒者的契约(Contract),它必须再次轮询你的 future 。否则,Future::poll 之间可能存在竞争条件。 call 和 future 的对应物,它实际上做了一些工作。

我们来看一个例子:

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(()),
        };
    }
}

时间点(1) ,future 已经决定它还没有准备好,但是有可能轮询线程在这里暂停,并且工作线程被调度并完成了它的工作。

然后工作线程将调用唤醒器并请求再次轮询 future 。如果唤醒者决定不再轮询 future ,因为它现在正在轮询 future ,那么唤醒者将永远不会再次收到唤醒请求。

这意味着唤醒器可能会丢弃之前的唤醒请求poll被调用,但不允许丢弃唤醒请求
来到 future 的poll称呼。

我唯一的问题是:你为什么要重新安排轮询一帧?

由于您的实际工作必须在单独的线程中完成(而不是在 fn poll 内部),因此重新安排轮询没有任何意义。

关于asynchronous - 在轮询时唤醒 Rust future 是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59974095/

相关文章:

node.js - 如何将 Node.js 中到达速度过快的事件输入一一写入数据库

javascript - 被拖拽的物体逃跑

asynchronous - 是否有 Service Worker 启动 waitUntil 来延迟处理获取?

rust - 如何获得 syntax::ast::Ident 的绝对名称?

rust - 如何将 i32 数字的 Vec<> 加入字符串?

Scala 用于理解 Future、List 和 Option

node.js - 仅在回调nodejs中完成一次调用异步函数

rust - 从stdin读取整行,包括\n直到文件结束

scala - 如何连接两个 Scala Future

python - python中ThreadPool中每个线程的超时