Signal
はじめに
「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。言語はライブラリが命。ということでライブラリの使い方編。
今回は Signal です。
- 参考
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
- 個別記事へのリンクは全てここに集約してあります。
- リポジトリ ... https://github.com/Kray-G/kinx
- Pull Request 等お待ちしております。
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
簡単ながらシグナルをサポートしました。
Signal
Signal は、type
として Signal.SIGINT
と Signal.SIGTERM
のみサポート。Signal.trap(type, handler)
でシグナル・ハンドラを登録し、処理を実行する。ハンドラが登録されていない状態でシグナルを検知したら、プログラムが終了する。
Signal.trap(type, handler)
シグナル・ハンドラ(handler
)を登録する。id を返すので、登録解除したい場合は Signal.remove(id)
で登録したハンドラを解除できる。
ハンドラが明示的に false を返した(return false
した)場合、プログラムを終了する。
現時点ではハンドラは登録した順序でコールされるが、この順序を保証するかは決めていない。保証する必要があるかな?
Signal.remove(id)
id で示されたハンドラを解除する。
ブロッキング処理の中断
以下の組み込みメソッドでのウェイト中には検出して中断するようにしている。
System.sleep()
$stdin.getch()
$stdin.readLine()
サンプル
Ctrl-C では終了しないが、Ctrl-Break で終了する。ただし、Ctrl-C を 10 回受信したら、ループから抜けてプログラムを終了させる。
var trapped = 0;
Signal.trap(Signal.SIGINT, function() {
System.println("SIGINT");
++trapped;
});
Signal.trap(Signal.SIGTERM, function() {
System.println("SIGTERM");
return false;
});
while (trapped < 10) {
System.println("Trapped = %2d" % trapped);
System.sleep(1000);
}
System.println("Ended");
結果。
Trapped = 0
Trapped = 0
Trapped = 0
SIGINT
Trapped = 1
SIGINT
Trapped = 2
SIGINT
Trapped = 3
SIGINT
Trapped = 4
SIGINT
Trapped = 5
SIGINT
Trapped = 6
SIGINT
Trapped = 7
SIGINT
Trapped = 8
SIGINT
Trapped = 9
SIGINT
Ended
Windows で Ctrl-Break、または Linux で kill -15 [PID]
してみる。
Trapped = 0
Trapped = 0
Trapped = 0
SIGINT
Trapped = 1
SIGINT
Trapped = 2
SIGINT
Trapped = 3
Trapped = 3
SIGTERM
おわりに
今回は簡単に説明。シグナルは割り込みと同じで急にフローが変化するので、処理前後でつじつま合うようにするために結構手が入りました。内部仕様はもう少し変化するかもしれない。動作仕様は変わらない範囲で。
あと、Windows と Linux で色々仕様が違うのを何とかするのが大変。Linux だと fgets
とかシグナルで中断されないので siginterrupt()
とか使ってシステムコールから復帰させたりしないといけない。ハンドルされるタイミングも微妙に違う。
SIGINT
と SIGTERM
以外サポートする必要あるかな?
ではまた次回。