基于时间条件的两线程之间的数据发送与接收

编程语言 2026-07-11

继续讨论这个 话题
如何才能实现最高性能? 是否有可能在代码中避免克隆?以及如何正确计数纳秒? 我没能让纳秒的输出始终显示为九位数并带前导零以便清晰。 两个线程都需要在执行此任务之外还能做其他工作,但不能以牺牲数据传输和接收速度为代价。 如何组织代码才能实现这一点?

在此输入图片描述

mod.rs : pub mod txrx;

main.rs

use std::sync::mpsc; 
use std::time::{SystemTime, UNIX_EPOCH}; 
mod tst01; 
use tst01::txrx::{DataSR}; 

fn main() { 
   let (tx_01, rx_01) = mpsc::channel(); 
   let tx_01_clone: std::sync::mpsc::Sender<(SystemTime, Vec<String>)> = tx_01.clone(); 
   let (tx_02, rx_02) = mpsc::channel(); 
   let tx_02_clone: std::sync::mpsc::Sender<(SystemTime, SystemTime, Vec<String>, SystemTime)> = tx_02.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 mut arch: Vec<(SystemTime, SystemTime, Vec<String>, SystemTime, SystemTime)> = vec![]; 

   DataSR::sr(rx_01, tx_02_clone); 

   drop(tx_01); 
   drop(tx_02); // ? does not affect operation 

   let mut index_d: u16 = 0; 
   let mut t_send: u64 = SystemTime::now().duration_since(UNIX_EPOCH).expect("..info").as_secs(); 
   let mut t_now = SystemTime::now(); 
   println!("start from main:  {:?}", sys_hmsn(&t_now, 2)); 
   let mut flag_break = 1; 
   loop { 
      // SEND  from main to child (every 3 seconds): 
      if index_d == d.len() as u16 { flag_break = 0; } 
      t_now = SystemTime::now(); 
      if t_send + 3 <= t_now.duration_since(UNIX_EPOCH).expect("..info").as_secs() {  
         t_send = t_send + 3;          
         println!("index_d = {:?}", index_d); 
         let _ = tx_01_clone.send((t_now, d[index_d as usize].clone())); 
         index_d = index_d + 1;  
      } 

      // RECEIVED  from child: 
      if let Ok(val) = &rx_02.try_recv() { 
         arch.push((val.0, val.1, val.2.clone(), val.3, SystemTime::now())); 
         if flag_break == 0 { break; } 
       }; 
   } 

   println!("\n[send from main] - [rec in child]       - [data] -        [send from child] - [rec in main]\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); 
   for val in &arch { 
      if val.0 == SystemTime::UNIX_EPOCH { 
        println!("                                    {:?}    - [{}] - [{}]", &val.2, sys_hmsn(&val.3, 2), sys_hmsn(&val.4, 2));  
      } else { 
        println!("[{}] - [{}] -      {:?}    - [{}] - [{}]", sys_hmsn(&val.0, 2), sys_hmsn(&val.1, 2), &val.2, sys_hmsn(&val.3, 2), sys_hmsn(&val.4, 2)); 
      }    
   } 
   // println!("\narch = {:?}\n", &arch); 
} 


fn sys_hmsn(now: &SystemTime, time_zone: u64) -> String { 
   match now.duration_since(UNIX_EPOCH) { 
      Ok(duration) => { 
         let total_seconds = duration.as_secs(); 
         let nanoseconds = duration.subsec_nanos(); // Nanoseconds part within the last second 
         let hour = (total_seconds / 60 / 60 + time_zone) % 24; 
         let minute = (total_seconds / 60) % 60; 
         let second = total_seconds % 60; 
         hour.to_string() + &":".to_string() + &minute.to_string() + &":".to_string() + &second.to_string() + &".".to_string() + &nanoseconds.to_string()   
      }, 
      Err(e) => "System time error: ".to_string() + &e.to_string() 
   } 
}

txrx.rs

use std::thread; 
use std::time::{SystemTime, UNIX_EPOCH}; 
use std::sync::mpsc::Receiver; 
use crate::sys_hmsn; 

pub struct DataSR; 

impl DataSR { 
    pub fn sr(rx_01: Receiver<(SystemTime, Vec<String>)>, tx_02_clone: std::sync::mpsc::Sender<(SystemTime, SystemTime, Vec<String>, SystemTime)>) { 
        thread::spawn(move || { 
        let mut data: (SystemTime, SystemTime, Vec<String>, SystemTime) = (SystemTime::UNIX_EPOCH, SystemTime::UNIX_EPOCH, vec![], SystemTime::UNIX_EPOCH); // = Default::default(); 
        let mut t_now_child: SystemTime = SystemTime::now(); 
        println!("start from child: {:?}", sys_hmsn(&t_now_child, 2)); 
        let mut t_send_child: u64 = SystemTime::now().duration_since(UNIX_EPOCH).expect("..info").as_secs(); 
        let mut d_child = vec![];  
        loop { 
            // SEND  from child to main (every 2 seconds): 
            t_now_child = SystemTime::now(); 
            if t_send_child + 2 <= t_now_child.duration_since(UNIX_EPOCH).expect("..info").as_secs() {  
                t_send_child = t_send_child + 2;          
                if let Ok(val) = rx_01.try_recv() {         // rx_01.recv_timeout(Duration::from_millis(2000)) 
                    t_now_child = SystemTime::now(); 
                    data.0 = val.0;                         // systemtime: send from main; 
                    data.1 = t_now_child;                   // systemtime: received in child; 
                    data.2 = val.1;                         // data 
                    data.3 = SystemTime::now();             // systemtime: send from child;  
                    tx_02_clone.send(data.clone()).unwrap();// send data to the main thread; 
                    d_child = data.2; 
                } else { 
                    data.0 = SystemTime::UNIX_EPOCH; 
                    data.1 = SystemTime::UNIX_EPOCH; 
                    data.2 = d_child.clone(); 
                    data.3 = SystemTime::now(); 
                    tx_02_clone.send(data.clone()).unwrap();// send data to the main thread; 
                    // println!(" ~ [{:?}] - []", sys_hmsn(&t_now_child, 2));    
                } 
            } 
        } 
        }); 
    } 
}

Report

start from main:  "12:14:59.525580200" 
start from child: "12:14:59.525707500" 

index_d = 0  
index_d = 1  
index_d = 2  
index_d = 3  

[send from main] - [rec in child]     - [data] -        [send from child] - [rec in main] 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
                                   []                 - [12:15:1.4500]  - [12:15:1.25500]  
[12:15:2.0]  - [12:15:3.2400]  -   ["01", "02", "03"] - [12:15:3.3300]  - [12:15:3.16500] 
                                   ["01", "02", "03"] - [12:15:5.8300]  - [12:15:5.196700] 
[12:15:5.0]  - [12:15:7.2600]  -   ["04", "05", "06"] - [12:15:7.5800]  - [12:15:7.19000] 
[12:15:8.0]  - [12:15:9.1500]  -   ["07", "08", "09"] - [12:15:9.1600]  - [12:15:9.13700] 
                                   ["07", "08", "09"] - [12:15:11.5100] - [12:15:11.217900] 
[12:15:11.0] - [12:15:13.1700] -   ["10", "11", "12"] - [12:15:13.4800] - [12:15:13.12900]
arch =  
[ 
(SystemTime { intervals: 116444736000000000 }, SystemTime { intervals: 116444736000000000 }, [], SystemTime { intervals: 134180433010000045 }, SystemTime { intervals: 134180433010000255 }),  
(SystemTime { intervals: 134180433020000000 }, SystemTime { intervals: 134180433030000024 }, ["01", "02", "03"], SystemTime { intervals: 134180433030000033 }, SystemTime { intervals: 134180433030000165 }),  
(SystemTime { intervals: 116444736000000000 }, SystemTime { intervals: 116444736000000000 }, ["01", "02", "03"], SystemTime { intervals: 134180433050000083 }, SystemTime { intervals: 134180433050001967 }),  
(SystemTime { intervals: 134180433050000000 }, SystemTime { intervals: 134180433070000026 }, ["04", "05", "06"], SystemTime { intervals: 134180433070000058 }, SystemTime { intervals: 134180433070000190 }),  
(SystemTime { intervals: 134180433080000000 }, SystemTime { intervals: 134180433090000015 }, ["07", "08", "09"], SystemTime { intervals: 134180433090000016 }, SystemTime { intervals: 134180433090000137 }),  
(SystemTime { intervals: 116444736000000000 }, SystemTime { intervals: 116444736000000000 }, ["07", "08", "09"], SystemTime { intervals: 134180433110000051 }, SystemTime { intervals: 134180433110002179 }),  
(SystemTime { intervals: 134180433110000000 }, SystemTime { intervals: 134180433130000017 }, ["10", "11", "12"], SystemTime { intervals: 134180433130000048 }, SystemTime { intervals: 134180433130000129 }) 
]

解决方案

你不需要变量 data,因为你在循环内已经完全重新赋值了它。此外,由于你没有对它们进行修改,你可以将你的 Vec<String> 替换为 Arc<[String]>,它是廉价可克隆的(因为克隆它只涉及增加引用计数,而不复制实际数据):

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

struct DataSR;

impl DataSR {
    pub fn sr(
        rx_01: Receiver<(SystemTime, Arc<[String]>)>,
        tx_02_clone: std::sync::mpsc::Sender<(SystemTime, SystemTime, Arc<[String]>, SystemTime)>,
    ) {
        thread::spawn(move || {
            //let mut data: (SystemTime, SystemTime, Vec<String>, SystemTime) = (SystemTime::UNIX_EPOCH, SystemTime::UNIX_EPOCH, vec![], SystemTime::UNIX_EPOCH); // = Default::default();
            let mut t_now_child: SystemTime = SystemTime::now();
            println!("start from child: {:?}", sys_hmsn(&t_now_child, 2));
            let mut t_send_child: u64 = SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .expect("..info")
                .as_secs(); // секунды в u64;
            let mut d_child = Arc::from(vec![]);
            loop {
                // SEND  from child to main (every 2 seconds):
                t_now_child = SystemTime::now();
                if t_send_child + 2
                    <= t_now_child
                        .duration_since(UNIX_EPOCH)
                        .expect("..info")
                        .as_secs()
                {
                    t_send_child = t_send_child + 2;
                    if let Ok(val) = rx_01.try_recv() {
                        // rx_01.recv_timeout(Duration::from_millis(2000))
                        t_now_child = SystemTime::now();
                        d_child = val.1.clone();
                        tx_02_clone
                            .send((val.0, t_now_child, val.1, SystemTime::now()))
                            .unwrap(); // send data to the main thread;
                    } else {
                        tx_02_clone
                            .send((
                                SystemTime::UNIX_EPOCH,
                                SystemTime::UNIX_EPOCH,
                                d_child.clone(),
                                SystemTime::now(),
                            ))
                            .unwrap(); // send data to the main thread;
                                       // println!(" ~ [{:?}] - []", sys_hmsn(&t_now_child, 2));
                    }
                }
            }
        });
    }
}

fn main() {
    let (tx_01, rx_01) = mpsc::channel();
    let (tx_02, rx_02) = mpsc::channel();

    let d: Vec<Arc<[String]>> = vec![
        Arc::from(vec!["01".to_string(), "02".to_string(), "03".to_string()]),
        Arc::from(vec!["04".to_string(), "05".to_string(), "06".to_string()]),
        Arc::from(vec!["07".to_string(), "08".to_string(), "09".to_string()]),
        Arc::from(vec!["10".to_string(), "11".to_string(), "12".to_string()]),
    ];
    let mut arch: Vec<(
        SystemTime,
        SystemTime,
        Arc<[String]>,
        SystemTime,
        SystemTime,
    )> = vec![];

    DataSR::sr(rx_01, tx_02);

    let mut index_d: u16 = 0;
    let mut t_send: u64 = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("..info")
        .as_secs();
    let mut t_now = SystemTime::now();
    println!("start from main:  {:?}", sys_hmsn(&t_now, 2));
    let mut flag_break = 1;
    loop {
        // SEND  from main to child (every 3 seconds):
        if index_d == d.len() as u16 {
            flag_break = 0;
        }
        t_now = SystemTime::now();
        if t_send + 3 <= t_now.duration_since(UNIX_EPOCH).expect("..info").as_secs() {
            t_send = t_send + 3;
            println!("index_d = {:?}", index_d);
            let _ = tx_01.send((t_now, d[index_d as usize].clone()));
            index_d = index_d + 1;
        }

        // RECEIVED  from child:
        if let Ok(val) = &rx_02.try_recv() {
            arch.push((val.0, val.1, val.2.clone(), val.3, SystemTime::now()));
            if flag_break == 0 {
                break;
            }
        };
    }

    println!("\n[send from main] - [rec in child]       - [data] -        [send from child] - [rec in main]\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
    for val in &arch {
        if val.0 == SystemTime::UNIX_EPOCH {
            println!(
                "                                    {:?}    - [{}] - [{}]",
                &val.2,
                sys_hmsn(&val.3, 2),
                sys_hmsn(&val.4, 2)
            );
        } else {
            println!(
                "[{}] - [{}] -      {:?}    - [{}] - [{}]",
                sys_hmsn(&val.0, 2),
                sys_hmsn(&val.1, 2),
                &val.2,
                sys_hmsn(&val.3, 2),
                sys_hmsn(&val.4, 2)
            );
        }
    }
    // println!("\narch = {:?}\n", &arch);
}

fn sys_hmsn(now: &SystemTime, time_zone: u64) -> String {
    match now.duration_since(UNIX_EPOCH) {
        Ok(duration) => {
            let total_seconds = duration.as_secs();
            let nanoseconds = duration.subsec_nanos(); // Nanoseconds part within the last second
            let hour = (total_seconds / 60 / 60 + time_zone) % 24;
            let minute = (total_seconds / 60) % 60;
            let second = total_seconds % 60;
            hour.to_string()
                + &":".to_string()
                + &minute.to_string()
                + &":".to_string()
                + &second.to_string()
                + &".".to_string()
                + &nanoseconds.to_string()
        }
        Err(e) => "System time error: ".to_string() + &e.to_string(),
    }
}

Playground

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章