Node.js API (process) - シグナルイベント

プログラムの外部から終了等の操作をしたい場合、 Unix 系ではシグナルを使用します。 Windows ではシグナルはないのですが、 Node.js ではある程度仮想的に対応してくれます。
今回は Node.js でのシグナル処理について説明します。

なお、Node.js ではシグナル処理は 標準モジュール の一つである Process モジュールで機能が提供されています。

シグナルの送信

まずは Node.js でシグナルを送信方法です。
送信はグローバルオブジェクトである processkill メソッドを呼び出します。
process.kill(pid[, signal])
 // ID が 8888 のプロセスに対して SIGINT を送信
 process.kill(8888, 'SIGINT');
このメソッド名は Unix にある kill コマンドから来ています。 signal の引数を省略時には、 kill コマンドのように SIGTERM を送信します。

シグナルの送信がなぜ kill コマンドなのかというと、おそらく外部からシグナルを送る場合、プロセスを終了させるためのものが多いからだと思います。
kill もそうですが、子プロセスの生成を spawn(産卵)、親プロセスが終了したのに終わらないプロセスを zombie(ゾンビ) と生き死にかかわる呼び名が多いです。


なお、 Windows ではシグナルの送信は対応していません。
一応、 SIGINT, SIGTERM, SIGKILL は送れるようになっていますが、 実際に送っているのではなく、単にプロセスを強制終了させます。 また、これら以外のシグナルを送信しようとするとエラーが発生します。

シグナル受信イベント

シグナルを受け取ると process オブジェクトはシグナル名をイベント名としたイベントを発行します。 シグナルのイベントにリスナーを登録することによって、デフォルトの動作を変更することができます。
以下の例では SIGINT にリスナーを登録しています。
 process.on('SIGINT', () => {
     console.log('Got SIGINT. ');
 });
SIGINT を受け取るとデフォルトでは終了しますが、リスナーを登録したことによって終了しなくなります。
ただし、後述するように登録できないシグナルや登録してもデフォルトの動作が変わらないシグナルもあります。

終了シグナル

シグナルでポイントになるのが、プロセスの終了のためのシグナルです。 それらのシグナルを以下の表にあげました。

シグナル 機能 説明
SIGHUP 1 端末切断(Hang UP) 端末エミュレーターやコンソールを閉じた場合に発生。
Windows でもコンソールを閉じると発生するが、リスナーを登録しても 10 秒程度で無条件に終了する。
SIGINT 2 割り込み(INTerapt) 一般的にキーボードの Ctrl+C で発生。 キーボードから発信は Windows も対応
SIGBREAK - 停止 Windows 用のシグナルで Ctrl+Break で発生
SIGKILL 9 強制終了 リスナーの登録不可
SIGTERM 15 終了(TERMinate) kill コマンドの省略時のデフォルト。 Windows 未対応


デフォルトでは Node.js はこれらのシグナルを受信するとプログラムをすぐに終了します。
これは SIGKILL を除いて、リスナーを登録して動作を変更することができます。 ただ、慣習的なものもあるので、対応を含めて個別に紹介していきます。

SIGTERM, SIGKILL

SIGTERM通常の終了で、 SIGKILL強制終了です。 kill コマンドのデフォルトは、名前と違って SIGKILL ではなく、 SIGTERM の方になっています。

終わる前に後処理をしたいというときにイベントをキャッチします。
 process.on('SIGTERM', () => {
     console.log('Got SIGTERM. ');
     // 後処理など
     // :
     process.exit(128+15);
 });
終了時の終了ステータスには慣習があります。それらについては以前の記事を見て下さい。 なお、SIGTERM を受け取っても終了させないというのはあまりよくありません。 外部から終了する手段をなくすのは危険ですし、そもそも SIGKILL の動作は変更できません。

SIGINT, SIGBREAK

SIGINT は割り込みと言いつつ、基本は終了します。 それも強制終了という扱いなどではなく、簡単なプログラムでは Ctrl+C を通常の終了方法としているものもあります。
ただ、 CUI で Ctrl+C を使いたいという時もあるので、 これで終了しないプログラムも結構あります。


SIGBREAK は SIGINT と同じような用途ですが、強制終了の意味合いが強い気がします。 Ctrl+Break はそんなに押すようなキーではないですし、そもそも知らない人も多いので、 そのままにしておいてもいいのではないかとは思います。
 process.on('SIGBREAK', () => {
     console.log('Got SIGBREAK. ');
     process.exit(1);
 });

SIGHUP

SIGHUP は端末エミュレーターやコンソールを閉じると発生するイベントです。 通常、端末を切る際にはそこで実行させていたコマンドも終了させます。

サーバーなどで端末切っても動かしたいということはありますが、そういうときは nohup コマンドを使うので、 終了しないようにする必要はありません。
使い勝手のために SIGHUP で終わらないようにしてもよいですが、 その場合はオプションを付けて起動した場合のみにしておきます。 デフォルトで終わらないのは、ユーザーが気付かずにプロセスを残す危険性が高くなります。
 process.on('SIGHUP', ()=> {
     console.log('Got SIGHUP. ');
     // -d オプションが付いていたら、終了しない
     if (process.argv[2] != '-d') {
        process.exit(128+1);
     }
 });
なお、 Windows ではリスナーを登録しても、しばらくすると無条件で終了します。 終了を止めることはできませんし、ここで後処理を入れても完了できる保証はありません。

また、 Unix 系ではデーモンなどのように動かし続け、ユーザーによる起動をあまり想定していないプログラムでは SIGHUP は終了ではなく、設定の再読み込みとして使われます。 ただ、 Node.js でデーモンを作るということはあまり無いかと思います。

その他のシグナル

シグナルというのは、まだまだあるのですが、終了シグナル以外で Node.js のドキュメントで紹介されていたのを紹介します。

シグナル 説明
SIGUSR1 SIGUSR1, SIGUSR2 はプログラム側で自由に使っていいシグナルとして用意されてる。
Node.js ではそのうちの SIGUSR1 をデバッガーが起動に充てている。 リスナーの登録はできるが、デバッガーの起動を止めることはできない
SIGPIPE 接続の切れたソケットに書き込みを行うと発生。デフォルトではプロセスの終了。
SIGWINCH コンソールのサイズが変更された場合に発生。 Windows でもカーソルの移動などで送信。
SIGSTOP 一時停止用シグナル。 Node.js では設定不可

サンプルコード

今回は先にサンプルコードを紹介します。各ファイルはリンクの [名前を付けて保存] で取得出来ます。


送信用のスクリプトです。 引数に プロセス ID とシグナル名を指定して、シグナルを送信します。
$ node process_signal_kill.js 8132 SIGINT


受信側のスクリプトです。 起動すると以下のことを行います。
$ node process_signal_rec.js 
 Process ID =  9432
ちなみに exit イベントが発生せず、終了ステータスが表示されない場合、 Unit 系では $?、 Windows では %ERRORLEVEL% で表示できます。


また、後述するシグナルイベントの取得例を追加したサンプルも用意しています。 node コマンドの使い方について詳しくは以前の記事をご覧ください。
関連記事
Prev.    Category    Next 

Facebook コメント


コメント

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
114位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
15位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

12月 | 2025年01月 | 02月
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。