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