Rust使用futures_signals时run_until执行Future永久阻塞
核心原因
程序永久阻塞的根本原因是:Mutable 生成的Signal是永不自动终止的无限事件流。
- Signal的设计逻辑是:只要底层绑定的
Mutable实例还存活,它就会持续等待值的变更,永远不会返回终止标记,对应的for_each组合子生成的Future也就永远不会走到完成状态。 - 你的代码运行时只触发了一次初始值推送:Signal第一次被执行器轮询时,会立刻吐出当前存的初始值
5,之后就进入挂起状态等待后续值变更。但你没有写任何修改my_state的逻辑,也没有主动终止流、销毁Mutable,所以Future会一直处于Pending状态,run_until自然会无限阻塞,永远走不到打印Done!的逻辑。
常见解决方式
根据你的业务需求选对应方案即可:
- 如果只需要获取初始值、不需要监听后续变更:给流加
take(1)限制,拿到第一个值后就主动终止流:
use futures_signals::signal::Mutable; use futures_signals::signal::SignalExt; use futures::executor::LocalPool; use futures::StreamExt; fn main(){ let my_state = Mutable::new(5); let future = my_state.signal() .to_stream() .take(1) // 取1个值后立即结束流 .for_each(|value| { println!("{}", value); async {} }); println!("Awaiting..."); let mut pool = LocalPool::new(); pool.run_until(future); println!("Done!"); }
- 如果需要在特定条件下停止监听:可以用
abortable给Future加终止控制,或者在满足业务条件时主动drop掉这个监听Future,执行器就会正常退出。 - 如果需要全局持续监听值变更:不要用
run_until等待这个Future完成——这类常驻监听逻辑本来就是要伴随程序整个生命周期运行的,你可以把它spawn到执行器上,再单独跑其他业务逻辑即可。
内容的提问来源于stack exchange,提问作者Blue7
相关产品推荐
相关产品推荐

