如何在Rust中实现可跨线程修改的可变间隔执行函数?
动态修改Tokio Interval的周期
Tokio的Interval本身不支持直接修改周期,但可以通过替换Interval实例的方式实现动态更新。结合消息通道接收新的Duration后,创建新的Interval替换旧的即可,以下是完整实现:
use tokio::time::{self, Duration, Interval}; use tokio::sync::mpsc::Receiver; use std::error::Error; fn update() { println!("update"); } pub async fn setup_changer(mut rx_dur: Receiver<Duration>) -> Result<(), Box<dyn Error>> { // 初始化默认间隔(这里设为1秒,可根据需求调整) let mut interval = time::interval(Duration::from_secs(1)); loop { tokio::select! { // 接收新的间隔时长,替换旧的Interval Some(new_dur) = rx_dur.recv() => { interval = time::interval(new_dur); println!("间隔已更新为 {:?}", new_dur); } // 间隔触发时执行任务 _ = interval.tick() => { update(); } } } } // 示例运行代码 #[tokio::main] async fn main() -> Result<(), Box<dyn Error>> { let (tx_dur, rx_dur) = tokio::sync::mpsc::channel(10); // 启动动态间隔任务 tokio::spawn(async move { setup_changer(rx_dur).await.unwrap(); }); // 模拟发送新间隔:3秒后改为2秒一次 tokio::time::sleep(Duration::from_secs(3)).await; tx_dur.send(Duration::from_secs(2)).await.unwrap(); tokio::time::sleep(Duration::from_secs(10)).await; Ok(()) }
关键说明
- 使用
tokio::select!同时监听两个异步事件:通道的新消息、Interval的tick触发 - 每次收到新的
Duration时,直接创建新的Interval覆盖旧实例,后续tick会自动使用新周期 Interval::tick()是异步方法,每次调用会等待下一个间隔触发,无需手动重置
内容的提问来源于stack exchange,提问作者Liran
相关产品推荐
相关产品推荐

