首页 > 解决方案 > 在 Rust 的 sigint 上唤醒一个睡眠线程?

问题描述

考虑以下简单的 Rust 程序:

use std::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use ctrlc;

static running: AtomicBool = AtomicBool::new(true);

fn main() {

    // Set up a thread that registers the sigint signal.
    ctrlc::set_handler(|| {
        running.store(false, Ordering::SeqCst);
    });

    // Loop as long as the signal has not been registered.
    while running.load(Ordering::SeqCst) {
        println!("Hello!");
        thread::sleep(Duration::from_secs(10));
    }
    println!("Goodbye!");

}

它打印“你好!” 每十秒一次,直到有人按下 Ctrl+C,然后打印“再见!” 并退出。问题是如果在线程进入睡眠状态后立即按下 Ctrl+C。然后用户必须等待将近十秒钟,直到程序退出。

有没有办法解决这个问题,并在收到 sigint 信号时以某种方式唤醒线程?如果有帮助,我准备将ctrlc依赖项更改为其他内容。

我能想出的唯一解决方案是在十个一秒的间隔内睡觉,在每次醒来时再次入睡之前检查信号。有没有更简单更漂亮的方法呢?

标签: multithreadingrustsleepsigint

解决方案


正如文档所说:

在 Unix 平台上,底层系统调用可能会被虚假唤醒或信号处理程序中断。为了确保睡眠至少在指定的持续时间内发生,此函数可能会多次调用该系统调用。不支持纳秒精度睡眠的平台将dur四舍五入到他们可以睡眠的最接近的时间粒度。

所以,我建议你直接使用更底层的函数,有一个 crates 封装它shuteye,但我不知道它是否是一个好。


推荐阅读