Introduzione ai SIGNAL in Rust

Mattepuffo's logo
Introduzione ai SIGNAL in Rust

Introduzione ai SIGNAL in Rust

In general un SIGNAL è un "software interrupt" (scusate ma non saprei come tradurlo in italiano) che viene inviato dal sistema o da un processo per notificare un evento.

Ad esempio quando lanciate un comando nel terminale e poi premte CTRL+C per interromperlo; quello è un SIGNAL.

In questo articolo vediamo un esempio basico di come usarli in Rust e tokio; l'esempio funzionerà in ambito UNIX-like, dove abbiamo questi SIGNAL:

Signal type Use
SIGHUP, code: 1 This signal is sent to a process when its controlling terminal is closed or disconnected
SIGINT, code: 2 This signal is sent to a process when the user presses Control+C to interrupt its execution
SIGQUIT, code: 3 This signal is similar to SIGINT but is used to initiate a core dump of the process, which is useful for debugging
SIGILL, code: 4 This signal is sent to a process when it attempts to execute an illegal instruction
SIGABRT, code 6 This signal is sent to a process when it calls the abort() function
SIGFPE, code: 8 This signal is sent to a process when it attempts to perform an arithmetic operation that is not allowed, such as division by zero
SIGKILL, code: 9 This signal is used to terminate a process immediately and cannot be caught or ignored
SIGSEGV, code: 11 This signal is sent to a process when it attempts to access memory that is not allocated to it
SIGTERM This signal is sent to a process to request that it terminate gracefully. Code: 15
SIGUSR1, code: 10 These signals can be used by a process for custom purposes
SIGUSR2, code: 12 Same as SIGUSR1, code: 10

Qui sotto il codice di esempio:

use tokio::signal::unix::{signal, SignalKind};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut sigint = signal(SignalKind::interrupt())?;

    match sigint.recv().await {
        Some(()) => println!("SIGINT signal ricevuto"),
        None => eprintln!("Terminato prima del SIGINT signal"),
    }

    for num in 0..10 {
        println!("{}", num)
    }

    Ok(())
}

Se lanciate cargo run in console non vedrete nulla fino a che non date CTRL+C; alla fine vedrete questo:

$ cargo run
   Compiling test_rust v0.1.0 (/home/fermat/TEST/test_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.52s
     Running `target/debug/test_rust`
^CSIGINT signal ricevuto
0
1
2
3
4
5
6
7
8
9

Ovviamente possiamo molto di più, ma non ho avuto modo di sperimentare oltre al momento.

Enjoy!


Condividi

Commentami!