如何在Rust中捕获信号

ban*_*l23 12 rust

我正在尝试编写一些能够捕获SIGTERM信号的代码.

我找到了这个,我还发现了如何处理Rust中的阻塞i/o,或者一般来说长时间运行外部函数调用.

但是在目前的Rust版本(每晚0.12)中,它似乎std::io::signal::Listener被删除了.它被放在别的地方吗?如果是这样,有人会指出我如何捕捉信号?

Blu*_*lue 14

似乎现在实现这一点相当简单。Rust 中的命令行应用程序的信号处理部分讨论了这个概念,并提到了ctrlc crate 来处理该特定信号,以及signal-hook crate 来处理一般信号。

通过指南,使用信号挂钩应该很简单:

use std::{error::Error, thread};
use signal_hook::{iterator::Signals, SIGTERM};

fn main() -> Result<(), Box<Error>> {
    let signals = Signals::new(&[SIGTERM])?;

    thread::spawn(move || {
        for sig in signals.forever() {
            println!("Received signal {:?}", sig);
        }
    });

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*eev 8

我相信std::io::signal拉取请求中删除了模块.声称正确的信号处理从未在本机运行时正确实现,因此无论如何您可能无法使用它.似乎是这个问题的跟踪问题.

与此同时,我认为,您将不得不从最低级别的不安全功能下拉libc.


Alb*_*eal 6

在撰写本答案时,有一个内置信号的RFC.

我已经使用了一些成功chan-signal箱子:

#[macro_use]
extern crate chan;
extern crate chan_signal;

use chan_signal::Signal;

fn main() {
    // Signal gets a value when the OS sent a INT or TERM signal.
    let signal = chan_signal::notify(&[Signal::INT, Signal::TERM]);
    // When our work is complete, send a sentinel value on `sdone`.
    let (sdone, rdone) = chan::sync(0);
    // Run work.
    ::std::thread::spawn(move || run(sdone));

    // Wait for a signal or for work to be done.
    chan_select! {
        signal.recv() -> signal => {
            println!("received signal: {:?}", signal)
        },
        rdone.recv() => {
            println!("Program completed normally.");
        }
    }
}

fn run(_sdone: chan::Sender<()>) {
    println!("Running work for 5 seconds.");
    println!("Can you send a signal quickly enough?");
    // Do some work.
    ::std::thread::sleep_ms(5000);

    // _sdone gets dropped which closes the channel and causes `rdone`
    // to unblock.
}
Run Code Online (Sandbox Code Playgroud)