time_check_loop/
lib.rs

1use std::thread;
2use std::time::Duration;
3use std::time::SystemTime;
4use std::sync::{Arc,Mutex};
5
6///将一个需要执行的函数当作闭包传递到子线程中循环执行,
7/// 
8/// Pass a function that needs to be executed as a closure to a child thread for loop execution,
9///
10/// 循环的同时有一个时间循环的线程配套,
11/// 
12/// At the same time as the loop, there is a time loop thread matching,
13/// 
14/// 需要执行的函数每执行一次,会更新一次执行时间
15/// 
16/// The execution time of the function that needs to be executed is updated every time it is executed
17/// 
18/// 时间循环函数一次sleep时间为time_check,执行时间距离上次执行时间大于四倍time_check则退出循环 
19/// 
20/// The time loop function has a sleep time of time_ Check, the execution time is greater than four times the last execution time_ Check to exit the loop
21/// 
22/// 注意如果执行的函数中有阻塞(例如io输入),会发生时间循环子线程退出,函数执行循环子线程一直在等待直到有IO输入或者main函数退出 
23/// 
24/// Note that if there is a block in the executed function (such as IO input), a time loop sub thread will exit, and the function execution loop sub thread will wait until there is IO input or the main function exits
25/// # Example
26/// 
27/// ```
28/// use std::thread;
29/// use std::time::Duration;
30/// //需要循环一次的函数
31/// //Functions that need to be iterated once
32///fn text_fn(i:u64) {
33///    let mut buffer = String::new();
34///    std::io::stdin().read_line(&mut buffer).unwrap();
35///    println!("text is {}",buffer);
36///    thread::sleep(Duration::from_secs(i));
37///    }
38///fn main() {   
39///    let time_check = 5;//单位为秒  Unit in seconds
40///      thread::spawn ( 
41///         move|| {
42///              time_check_loop::loop_time_check(move || {text_fn(1);},time_check); 
43///         }
44///     );
45///     loop{
46///     thread::sleep(Duration::new(5,0));
47///     };
48///}
49///```
50pub fn loop_time_check<F>(job:F,time_check:u64) 
51    
52    where
53    F:FnOnce() + Send + 'static+ Copy,
54    {
55    let time_loop = time_check; //设置循环检测时间 Set cycle detection time
56    let send_time = 2*time_loop;  //设置心跳时间(暂时没用的),本来是给物联网这类留的,为了模块化删除了物联网部分 Setting the heartbeat time (temporarily useless) was originally reserved for the Internet of Things, but the IoT section was removed for modularity
57    let exit_time = 4*time_loop; //设置超时时间 Set timeout time
58
59    let time_first = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
60
61    let time_out = Arc::new(Mutex::new(time_first));
62    let time_in = Arc::clone(&time_out);
63
64    let (tx, rx) = std::sync::mpsc::channel();
65    let time_in = time_in.clone();
66    thread::spawn(move || {
67        loop{
68            job();
69            let in_now_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
70            //向外部传递了时间
71            *time_in.lock().unwrap()= in_now_time;
72            match rx.try_recv() {
73                Ok(some) => {
74                    match some {
75                        "exit" => {
76                            eprintln!("the action thread receive meg {})",some);
77                            break;
78                        }
79                        "are you here" => {
80                            eprintln!("the action thread receive meg {}",some);
81                            //心跳处理
82                        }
83                        _ => {
84                            eprintln!("the action thread receive meg {} is unknow)",some);
85                            break;
86                        }
87                    }
88                }
89                Err(_err) => {
90                    eprintln!("the action thread haven't receive meg still run)");
91                }
92            }
93        }
94    });
95    eprintln!("start time loop");
96    loop {
97        let out_now_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
98        let dif_time = out_now_time - *time_out.lock().unwrap();
99        println!("time loop differences time is {} ", dif_time.as_secs());
100        
101        //大于超时时间就退出,大于心跳时间发送心跳 Set the timeout time to exit if it is greater than the timeout time, and send a heartbeat if it is greater than the heartbeat time
102        if dif_time.as_secs() > send_time {
103            if dif_time.as_secs() > exit_time {
104                tx.send("exit").unwrap();
105                eprintln!("time loop exit");
106                break
107            }
108            //If there is no corresponding heartbeat processing set, there is no need to send meg (after sending meg, the execution function can only consume one meg every time it executes a loop)
109            //没有设置相应心跳处理,就不用send meg (send meg后执行函数每执行一次循环,才能消费一个meg)
110            //tx.send("are you here").unwrap(); 
111            eprintln!("time loop send meg");
112        }
113        thread::sleep(Duration::from_secs(time_loop));
114    }
115}