如何在 Rust 中执行可中断睡眠?
How do I perform interruptible sleep in Rust?
我正在编写一个每 2 秒执行一次操作的 Rust 程序。该程序还使用 ctrlc
crate 来处理中断。但是,在某些情况下,我必须在终止进程时等待最多 2 秒。我正在使用默认的 std::thread::sleep
函数,我似乎无法中断它。
我的问题来了。我可以让我的程序以一种可中断的方式休眠吗?换句话说,Rust 是否具有中断休眠程序的默认功能?我知道 C 在收到 SIGINT 信号时会自动中断任何睡眠功能。
您的信号处理程序需要使 运行 线程以某种方式 停止或在捕获到信号时退出进程。
退出进程很简单:清理完成后在信号处理程序中调用 std::process::exit()
。
将信号转发到休眠线程更难,您可以通过在捕获 SIGINT 时在 Arc<AtomicBool>
中设置一些标志并在两次检查之间用较短的间歇性睡眠反复检查该标志而不是一个更长的睡眠时间。
您还可以提出一个基于通道的解决方案,您的 ctrlc 处理程序通过广播通道与 运行 线程通信,并等待它们以某种 done
消息响应退出进程。此 done
消息可以通过关闭处理程序传递给 运行 线程的通道的发送端。然后它可以等待超时,然后用 std::process::exit
.
强制退出
如果您只想清理并退出,那么您可以按照其他答案的建议在信号处理程序中调用 std::process::exit
。但是,如果您希望您的线程停止以便您的应用程序可以继续执行其他任务,您可以使用通道和 recv_timeout
来获得可中断的睡眠:
use std::thread;
use std::time::Duration;
use std::sync::mpsc;
let (send, recv) = mpsc::channel();
thread::spawn(move || {
// When you want to sleep
if let Ok(_) = recv.recv_timeout (Duration::from_secs (2)) {
// Sleep was interrupted
return;
}
// Slept for 2s, proceeding
});
// And elsewhere when you want to interrupt the thread:
send.send(());
我正在编写一个每 2 秒执行一次操作的 Rust 程序。该程序还使用 ctrlc
crate 来处理中断。但是,在某些情况下,我必须在终止进程时等待最多 2 秒。我正在使用默认的 std::thread::sleep
函数,我似乎无法中断它。
我的问题来了。我可以让我的程序以一种可中断的方式休眠吗?换句话说,Rust 是否具有中断休眠程序的默认功能?我知道 C 在收到 SIGINT 信号时会自动中断任何睡眠功能。
您的信号处理程序需要使 运行 线程以某种方式 停止或在捕获到信号时退出进程。
退出进程很简单:清理完成后在信号处理程序中调用 std::process::exit()
。
将信号转发到休眠线程更难,您可以通过在捕获 SIGINT 时在 Arc<AtomicBool>
中设置一些标志并在两次检查之间用较短的间歇性睡眠反复检查该标志而不是一个更长的睡眠时间。
您还可以提出一个基于通道的解决方案,您的 ctrlc 处理程序通过广播通道与 运行 线程通信,并等待它们以某种 done
消息响应退出进程。此 done
消息可以通过关闭处理程序传递给 运行 线程的通道的发送端。然后它可以等待超时,然后用 std::process::exit
.
如果您只想清理并退出,那么您可以按照其他答案的建议在信号处理程序中调用 std::process::exit
。但是,如果您希望您的线程停止以便您的应用程序可以继续执行其他任务,您可以使用通道和 recv_timeout
来获得可中断的睡眠:
use std::thread;
use std::time::Duration;
use std::sync::mpsc;
let (send, recv) = mpsc::channel();
thread::spawn(move || {
// When you want to sleep
if let Ok(_) = recv.recv_timeout (Duration::from_secs (2)) {
// Sleep was interrupted
return;
}
// Slept for 2s, proceeding
});
// And elsewhere when you want to interrupt the thread:
send.send(());