クレート
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() => {} //無シグナル時は何もしない
}
}