Buscar..


Observaciones

El óxido no tiene una forma adecuada, idiomática y segura de vincularse con las señales del sistema operativo, pero hay algunas cajas que proporcionan el manejo de la señal, pero son altamente experimentales e inseguras, así que tenga cuidado al usarlas.

Sin embargo, hay una discusión en el repositorio rust-lang / rfcs sobre cómo implementar el manejo de señales nativas para el óxido.

Discusión sobre RFCs: https://github.com/rust-lang/rfcs/issues/1368

Manejo de señal con caja de señal de chan.

La caja de señal de chan proporciona una solución para manejar la señal del sistema operativo utilizando canales, aunque esta caja es experimental y debe usarse con cuidado .

Ejemplo tomado 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.
}

Manipulación de señales con caja nix.

La caja nix proporciona una API de Rust de UNIX para manejar señales, sin embargo, requiere el uso de óxido no seguro, por lo que debe tener cuidado .

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

Ejemplo de Tokio

La caja de tokio-signal proporciona una solución basada en tokio para el manejo de señales. Sin embargo, todavía está en sus primeras etapas.

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow