Recherche…


Remarques

Rust ne dispose pas d'un moyen approprié et idiomatique pour communiquer avec les signaux du système d'exploitation, mais il y a des caisses qui fournissent un traitement du signal, mais elles sont très expérimentales et peu sûres .

Cependant, il y a une discussion dans le dépôt rust-lang / rfcs sur l'implémentation de la gestion du signal natif pour la rouille.

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

Traitement du signal avec caisse de signal de chan

La caisse de signal de chan fournit une solution pour gérer le signal de système d'exploitation en utilisant des canaux, bien que cette caisse soit expérimentale et devrait être utilisée avec soin .

Exemple tiré de 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.
}

Manipulation des signaux avec une caisse nix.

Le nix crate fournit une API UNIX Rust pour gérer les signaux, mais il faut utiliser une rouille non sécurisée pour être prudent .

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);
}

Exemple Tokio

La caisse de tokio-signal fournit une solution basée sur tokio pour gérer les signaux. Il est encore dans ses premiers stades cependant.

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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow