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}