Rustでシグナルを手軽に扱う
[2018.08.14 追記] chan-signalはdeprecatedになって、代わりにcrossbeam-channelとsignal-hookを使うことが推奨されています。
概要
なるほどUnixプロセスをRustで実装してみるということをやっていて、そこでシグナルを扱う章があったのですがあまり情報がない感じだったのと、今後Rustでもシグナルを扱いたい場面がでてきそうなので、試したことのメモを共有します。
Rustはstableで1.16前提です。
chan-signalを使う
Goのchannel/selectライクに非同期処理を書くことができるchanクレイトと、chanと合わせてシグナルを容易に扱うことができるchan-signalクレイトを使ってシグナルを扱ってみます。
2017年4月現在の最新バージョンはchan:0.1.19
、chan-signal:0.2.0
です。
最初はchan_signal
だけを使った例です。
[dependencies]
chan = "*"
chan-signal = "*"
extern crate chan_signal;
use chan_signal::Signal;
fn main() {
let s = chan_signal::notify(&[Signal::TERM, Signal::USR1]);
match s.recv() {
Some(s) => println!("signal={:?}", s),
_ => {}
}
}
SIGTERMとSIGUSR1を受信設定して1度だけ受信を待ち受けて、シグナル受信時にデバッグ出力します。(Ctrl-Cで停止できないので、kill -TERM PID
等で停止する必要があります。)
chanとchan-signalを組み合わせて使う
chanクレイトを使って、10秒後にメッセージを受信またはシグナルSIGINTの受信を同時に待ち受ける処理の例です。
#[macro_use]
extern crate chan;
extern crate chan_signal;
use chan_signal::Signal;
fn main() {
let s = chan_signal::notify(&[Signal::INT]);
let do_something = chan::after_ms(10_000);
chan_select! {
s.recv() -> signal => {
println!("signal={:?}", signal);
},
do_something.recv() => {
println!("do something");
}
}
}
実行して何もしなければ10秒後にdo something
を出力して終了し、途中でCtrl-C等でシグナルSIGINTを受信すればデバッグ出力して終了します。
手軽です。
chan
クレイトはそれ単体で面白い機構なので、もう少し中身見てみたり実際に使ってみたりしたいですね。
nixを使う
nixクレイトのsigaction
あたりを使えば、いわゆる生のxNIX APIを使う感覚でシグナルを扱う処理を実装できます。
2017年4月現在のnix
の最新バージョンは0.8.1
です。
[dependencies]
nix = "*"
以下は先ほどのchan
とchan-signal
を組み合わせた例をnix
で実装してみたものです。
#[macro_use]
extern crate chan;
extern crate nix;
use nix::sys::signal;
use nix::sys::signal::{sigaction, SigAction, SigHandler, SA_RESETHAND, SigSet};
extern "C" fn handle_signal(signum: i32) {
println!("handler. signal={}", signum);
}
fn main() {
let sa = SigAction::new(SigHandler::Handler(handle_signal), SA_RESETHAND, SigSet::empty());
unsafe { sigaction(signal::SIGINT, &sa) }.unwrap();
let do_something = chan::after_ms(10_000);
chan_select! {
do_something.recv() => {
println!("do something");
}
}
}
SA_RESETHAND
で1度だけ定義したハンドラ設定が有効になるので、実行後にCtrl-Cでhandler. signal=2
と表示され、もう一度Ctrl-Cでプログラムが終了します。(実行後何もしなければ10秒後にdo something
を出力して終了するのは変わりません。)
おわりに
以上、chan
chan-signal
nix
を使ったRustでのシグナルの扱いについてのメモでした。
Author And Source
この問題について(Rustでシグナルを手軽に扱う), 我々は、より多くの情報をここで見つけました https://qiita.com/hhatto/items/d226e66141996cbd25b8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .