LoginSignup
1
1

More than 5 years have passed since last update.

Rust シグナル メモ

Last updated at Posted at 2018-04-19

クレート

chan, chan-signal

宣言

#[macro_use]
extern crate chan;
extern crate chan_signal;

use chan_signal::Signal;

使い方

SIGINT待機

let signal = chan_signal::notify(&[Signal::INT, Signal::TERM]);

シグナル列を格納するバッファを作成

引数が0ならキューに、非0なら要素数1のバッファになります。

let (sdone, rdone) = chan::sync(0);

メイン処理をする関数を作成

fn 関数(_sdone: chan::Sender<()>, 引数...) {
/* 処理 */
}

メイン処理をさせるスレッドを作成

std::thread::spawn(move || 関数(sdone, 引数));

シグナル解析

chan_select! { //シグナル解析フェイズ
    signal.recv() -> signal => { //シグナル受信時
        if signal.unwrap() == Signal::INT { //もしシグナルがSIGINTならば
            /* 処理 */
            std::process::exit(0); //こうするとSIGINTっぽくなる
        }
    },
    rdone.recv() => {} //シグナルを受信してければ何もしない
}

全文

fn hoge() { // 並列化,シグナル処理の関数
    let signal = chan_signal::notify(&[Signal::INT]);
    let (sdone, rdone) = chan::sync(0);
    thread::spawn(move || fuga()); // fuga(): シグナルを受信するまで動かす関数
    chan_select! {
        signal.recv() => {
            // シグナル受信時の処理
        },
        rdone.recv() => {}
    }
}

悪い例

以下のような方法でもシグナル処理は可能だが、シグナル待機が必要なので速度が著しく低下してしまう。

while内で使用して常にシグナル待機
while true {
    let sig_int = chan_signal::notify(&[Signal::INT]); //SIGINTを待機
    let no_signal = chan::after_ms(20); //20msだけ待つ
    /* 処理 */
    chan_select! { //シグナル処理フェイズ
        sig_int.recv() -> signal => { //SIGINT時
            /* 処理 */
            std::process::exit(0); //こうするとSIGINTっぽくなる
        },
        no_signal.recv() => {} //無シグナル時は何もしない
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1