如何在Future::poll()中实现睡眠?代码陷入Pending状态
问题:自定义Future的poll方法中实现睡眠始终处于Pending状态
我希望在poll()方法中实现1秒睡眠,但代码始终处于Pending状态。根据我的理解,传入&mut cx后应该会在1秒后唤醒当前任务,相关代码如下:
use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::{Duration}; struct MyDelay {} impl Future for MyDelay { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { println!("poll"); let sleep = tokio::time::sleep(Duration::from_secs(1)); tokio::pin!(sleep); sleep.poll(cx) } } #[tokio::main] async fn main() { let delay = MyDelay{}; let a = delay.await; dbg!(a); }
问题原因
- 每次
poll被调用时,都会创建一个全新的tokio::time::sleepFuture:第一次调用poll返回Pending后,sleep会安排1秒后唤醒任务,但任务被唤醒再次调用poll时,又会创建新的sleep重新计时,之前的sleep完成信号完全无效。 MyDelay结构体没有保存任何状态,无法跟踪sleep的执行进度,导致循环往复永远无法完成。
修正方案
让MyDelay结构体持有tokio::time::sleep Future,仅在初始化时创建一次,后续poll复用同一个Future:
use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::Duration; use tokio::time::Sleep; struct MyDelay { sleep: Sleep, } impl MyDelay { fn new() -> Self { Self { sleep: tokio::time::sleep(Duration::from_secs(1)), } } } impl Future for MyDelay { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { println!("poll"); Pin::new(&mut self.sleep).poll(cx) } } #[tokio::main] async fn main() { let delay = MyDelay::new(); let a = delay.await; dbg!(a); }
修改后,MyDelay初始化时创建的sleep会被持续跟踪,当计时完成后,poll会返回Ready<()>,任务即可正常结束。
内容的提问来源于stack exchange,提问作者Anunaki
相关产品推荐
相关产品推荐

