Ricerca…


Osservazioni

La ruggine non ha un modo corretto, idiomatico e sicuro di navigare con i segnali del sistema operativo, ma ci sono alcune casse che forniscono la gestione del segnale ma sono altamente sperimentali e non sicure, quindi fai attenzione quando le usi.

Comunque c'è una discussione nel repository rug-lang / rfcs sull'implementazione della gestione del segnale nativo per la ruggine.

Discussione RFC: https://github.com/rust-lang/rfcs/issues/1368

Gestione del segnale con cassa dei segnali chan

La cassa del segnale chan fornisce una soluzione per gestire il segnale del sistema operativo usando i canali, sebbene questa cassa sia sperimentale e dovrebbe essere usata con attenzione .

Esempio preso da BurntSushi / 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.
}

Gestione dei segnali con nix crate.

La nix crate fornisce un'API Rust UNIX per gestire i segnali, tuttavia richiede l'utilizzo di ruggine non sicura, quindi è necessario fare attenzione .

use nix::sys::signal;

extern fn handle_sigint(_:i32) {
    // Be careful here...
}

fn main() {
    let sig_action = signal::SigAction::new(handle_sigint,
                                          signal::SockFlag::empty(),
                                          signal::SigSet::empty());
    signal::sigaction(signal::SIGINT, &sig_action);
}

Esempio di Tokio

La cassetta del tokio-segnale fornisce una soluzione basata su tokio per la gestione dei segnali. È ancora nelle sue prime fasi però.

extern crate futures;
extern crate tokio_core;
extern crate tokio_signal;

use futures::{Future, Stream};
use tokio_core::reactor::Core
use tokio_signal::unix::{self as unix_signal, Signal};
use std::thread::{self, sleep};
use std::time::Duration;
use std::sync::mpsc::{channel, Receiver};

fn run(signals: Receiver<i32>) {
    loop {
        if let Some(signal) = signals.try_recv() {
            eprintln!("received {} signal");
        }
        sleep(Duration::from_millis(1));
    }
}

fn main() {
    // Create channels for sending and receiving signals
    let (signals_tx, signals_rx) = channel();

    // Execute the program with the receiving end of the channel
    // for listening to any signals that are sent to it.
    thread::spawn(move || run(signals_rx));

    // Create a stream that will select over SIGINT, SIGTERM, and SIGHUP signals.
    let signals = Signal::new(unix_signal::SIGINT, &handle).flatten_stream()
        .select(Signal::new(unix_signal::SIGTERM, &handle).flatten_stream())
        .select(Signal::new(unix_signal::SIGHUP, &handle).flatten_stream());

    // Execute the event loop that will listen for and transmit received
    // signals to the shell.
    core.run(signals.for_each(|signal| {
        let _ = signals_tx.send(signal);
        Ok(())
    })).unwrap();
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow