You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不为Future调用Waker是否可行?会阻塞其他Future执行吗?

关于未触发wake的Future是否阻塞其他任务的问题

首先是你实现的代码:

use std::future::Future;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::task::{Context, Poll, Waker};

use arc_swap::ArcSwap;

struct MyFuture {
    flag: Arc<AtomicBool>,
    waker: Arc<ArcSwap<Option<Waker>>>,
}

impl MyFuture {
    fn change(&self) {
        if let Some(waker) = &*self.waker.load_full() {
            waker.wake_by_ref();
        }

        self.flag.store(true, Ordering::SeqCst);
    }
}

impl Future for MyFuture {
    type Output = Option<()>;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let flag = self.flag.load(Ordering::SeqCst);
        if flag {
            Poll::Ready(Some(()))
        } else {
            self.waker.store(Some(cx.waker().clone()).into());
            Poll::Pending
        }
    }
}

不会阻塞其他Future的执行。

Rust的异步运行时采用协作式调度:当某个Future的poll方法返回Poll::Pending时,调度器会将这个任务从当前执行队列中移除,把线程资源让给其他就绪的任务。只有当该Future对应的waker被唤醒时,调度器才会将它重新加入执行队列,再次调用它的poll方法。

所以即便你的change()永远不被调用,这个MyFuture只会一直处于挂起状态,不会占用线程执行时间,其他Future依然能正常被调度执行。

另外提个代码里的潜在问题:每次poll时都会直接覆盖waker存储的内容,如果存在多个不同的waker(比如任务被调度到不同线程执行),之前的waker会被丢弃,可能导致后续唤醒失效。可以考虑检查当前存储的waker是否与当前cx的waker一致,不一致时再更新,避免不必要的覆盖。

内容的提问来源于stack exchange,提问作者silverwen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:42:41