rust-lang-nursery / rust-cookbook

https://rust-lang-nursery.github.io/rust-cookbook
Creative Commons Zero v1.0 Universal
2.25k stars 284 forks source link

Unix signal handling #501

Open ghost opened 5 years ago

ghost commented 5 years ago

It'd be nice to include an example for signal handling on Unix-like platforms.

Currently, the go-to solution is to look up chan-signal (which is deprecated) and then copy-paste the example for the readme that is using signal-hook and crossbeam-channel:

extern crate crossbeam_channel as channel;
extern crate signal_hook;

fn notify(signals: &[c_int]) -> Result<channel::Receiver<c_int>> {
    let (s, r) = channel::bounded(100);
    let signals = signal_hook::iterator::Signals::new(signals)?;
    thread::spawn(move || {
        for signal in signals.forever() {
            s.send(signal);
        }
    });
    Ok(r)
}

By the way, I have a question: why are we creating a bounded(100) channel rather than unbounded()?

Also, check out this stopwatch that shows a neat example of using signal-hook and crossbeam-channel with the tick channel and select!. Perhaps we could add something like it to the cookbook.

cc @vorner @BurntSushi

vorner commented 5 years ago

By the way, I have a question: why are we creating a bounded(100) channel rather than unbounded()

My guess is, bounded channels are considered the „default“ and unbounded are used only if you have some reasons. Mostly because with bounded channels, there's no risk of exhausting the RAM if the reader doesn't keep up.

If the write end becomes blocked, the signals will get coalesced together, which is usually fine.

BurntSushi commented 5 years ago

@vorner's reasoning is exactly why I did it. I always try to use bounded channels unless there's a specific good reason to do otherwise.

ghost commented 5 years ago

Makes sense. But... (I don't know a lot about signal-hook) does that mean some signals could be dropped, e.g. if we send 1000 signals in quick succession?

vorner commented 5 years ago

It means that some instances of the signals might be dropped. But you'll always get at least one of each kind ‒ so if someone sends you 950 SIGINT and 50 SIGUSR1, you'll get at least one of each.

This is not a speciality of signal-hook, it's how the OS works ‒ signals have a flag semantics, if they happened since last time anyone looked, not how many times. Signal-hook only can magnify the effect under some circumstances.