Rust
Manejo de señales
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(); }