web-dev-qa-db-ja.com

Linuxでアプリケーションを強制終了せずにシグナルを送る方法は?

ウォッチドッグアプリケーションがあります。何らかの理由でクラッシュする可能性のあるメインアプリを監視します(悪いことはわかっていますが、これはポイントではありません)。

このウォッチドッグをプログラムして、SIGUSR1信号を受け入れ、アプリケーションの存在の監視を停止しました。私はそれを合図します

kill -SIGUSR1 `pidof myapp`

これは本当にうまくいきます。この機能が組み込まれていない古いバージョンのウォッチドッグにシグナルを送信しようとすると、問題が発生します。この場合、killシグナルはウォッチドッグを殺し(プロセスを終了します)、さらに複雑になります(デバイスの再起動) 。

この特定のシグナルが処理されない場合に終了しないように、SIGUSR1でウォッチドッグにシグナルを送る方法はありますか?

32
Eric

GNU docs からのシグナル処理:

SIGUSR1シグナルとSIGUSR2シグナルは、任意の方法で使用できるように確保されています。シグナルを受信するプログラムでシグナルハンドラを作成する場合、単純なプロセス間通信に役立ちます。 SIGUSR1およびSIGUSR2の使用を示す例は、「別のプロセスに信号を送る」セクションにあります。 デフォルトのアクションは、プロセスを終了することです

SIGINFOのデフォルトアクションは何もしないため、より適切な場合があります。

SIGINFO:情報リクエスト。 4.4 BSDおよびGNUシステムでは、ユーザーが正規モードでSTATUS文字を入力すると、このシグナルは制御端末のフォアグラウンドプロセスグループのすべてのプロセスに送信されます。シグナル:プロセスがプロセスグループのリーダーである場合、デフォルトのアクションは、システムおよびプロセスの実行内容に関するステータス情報を出力することです、それ以外の場合、デフォルトでは何もしない

[〜#〜] sighup [〜#〜] は、制御端末が閉じられたときに出力されますが、ほとんどのデーモンは端末に接続されていないため、「リロード」として使用することは珍しくありません。

デーモンプログラムは、SIGHUPを信号として使用して自分自身を再起動する場合があります。これは、変更された構成ファイルを再読み取りすることが最も一般的な理由です。

ところで、ウォッチドッグはプロセスを再起動する必要があるかどうかを知るために、時々設定ファイルを読み取ることができます。

ウォッチドッグの私の個人的なお気に入りは supervisor です。

$ supervisorctl start someapp
someapp: started

$ supervisorctl status someapp
someapp                RUNNING    pid 16583, uptime 19:16:26

$ supervisorctl stop someapp
someapp: stopped

kill -lはプラットフォーム上のシグナルのリストを返し、それらのいくつかを試しますが、SIGUSR1は悪い選択のようです。

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

[更新]

Carpetsmokerは、LinuxとBSDの動作の違いについてコメントしています。

SIGINFOはGNU libc&BSD; BSDでは説明どおりに動作しますが、Linuxでは存在しないか、SIGPWRと同じです... GNUこの点でlibcマニュアルは間違っているようです(kill -lの出力にもSIGINFOが表示されません)...なぜかわかりませんGNUがサポートしていません。非常に便利だからです... – Carpetsmoker

33
Paulo Scardine

SIGUSR1を受信したときのデフォルトのアクションは、ハンドラーが存在しない場合に終了することです。つまり、あなたはもうその信号であなたが望むことをすることができません。

ウォッチドッグを更新する以外には、できることは何もありません(シグナルを送信する前に、プログラム内からウォッチドッグのバージョンを区別できないと思います)。

3
Milan