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

如何实现子线程每2秒输出数据,无新数据时重复输出最后数据

如何实现子线程每2秒输出数据,无新数据时重复输出最后数据

我来帮你搞定这个需求!核心思路是把接收端的逻辑从「被动等数据才打印」改成「主动每2秒输出一次」——期间有新数据就更新缓存,没有就用上次的缓存兜底输出。

直接上修改后的代码,关键改动我后面给你拆解:

use std::thread;
use std::sync::mpsc;
use std::time::{SystemTime, UNIX_EPOCH, Duration};

fn main() {
    let (tx, rx) = mpsc::channel();
    let tx1: std::sync::mpsc::Sender<Vec<String>> = tx.clone();
    let d: Vec<Vec<String>> = vec![
        vec!["01".to_string(), "02".to_string(), "03".to_string()],
        vec!["04".to_string(), "05".to_string(), "06".to_string()],
        vec!["07".to_string(), "08".to_string(), "09".to_string()],
        vec!["10".to_string(), "11".to_string(), "12".to_string()]
    ];

    let _t = thread::spawn(move || {
        // 新增:保存最后一次收到的有效数据
        let mut last_data = Vec::new();
        // 循环主动尝试接收+输出,直到通道关闭
        loop {
            match rx.recv_timeout(Duration::from_secs(2)) {
                Ok(new_data) => {
                    // 收到新数据,更新缓存
                    last_data = new_data;
                    // 输出最新数据
                    print_current_data(&last_data);
                }
                Err(mpsc::RecvTimeoutError::Timeout) => {
                    // 超时(2秒没收到新数据),如果有缓存就输出
                    if !last_data.is_empty() {
                        print_current_data(&last_data);
                    }
                }
                Err(mpsc::RecvTimeoutError::Disconnected) => {
                    // 通道关闭,退出循环
                    break;
                }
            }
        }
    });

    drop(tx);
    for i in 0..d.len() {
        thread::sleep(Duration::from_millis(3000));
        tx1.send(d[i].clone()).unwrap();
    }
    // 等待子线程处理完最后一次输出,避免主线程提前退出
    thread::sleep(Duration::from_millis(2500));
}

// 抽离打印逻辑,复用代码更清爽
fn print_current_data(data: &[String]) {
    let sec = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("SystemTime went backwards")
        .as_secs() % 60;
    println!("[{:?}] - {:?}", sec, data);
}

关键改动拆解

  1. 接收逻辑从被动变主动:用rx.recv_timeout(Duration::from_secs(2))替代rx.iter(),每2秒强制触发一次动作——要么收到新数据更新缓存并输出,要么超时就用缓存的旧数据输出。
  2. 新增last_data缓存变量:专门存最后一次收到的有效数据,解决无新数据时的重复输出问题,避免每次都要重新整理数据。
  3. 抽离打印函数:把重复的时间戳计算、打印逻辑单独拎出来,减少代码冗余,也方便后续修改输出格式。
  4. 调整主线程收尾等待:最后多等2.5秒,确保子线程能输出最后一次的重复数据,不会因为主线程提前退出而被打断。

测试输出效果

这个代码跑起来会完全符合你的预期,输出类似:

[35] - ["01", "02", "03"]
[37] - ["01", "02", "03"]
[39] - ["04", "05", "06"]
[41] - ["04", "05", "06"]
[43] - ["07", "08", "09"]
[45] - ["07", "08", "09"]
[47] - ["10", "11", "12"]
[49] - ["10", "11", "12"]

备注:内容来源于stack exchange,提问作者inshade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:38:09