私はDebianストレッチ(systemd)を使用しています。 /usr/sbin/rsyslogd -n
を使用してフォアグラウンドでrsyslogデーモンを実行していて、 Ctrl+Z それを止める。プロセスの状態がTl
(停止、スレッド化)に変わりました。プロセスに複数のkill -15 <pid>
コマンドを発行しましたが、プロセスの状態は同じでした:Tl
。 fg
を実行すると、死亡しました。 3つの質問があります。
SIGSTOP
- edプロセスがSIGTERM
に応答しないのはなぜですか?なぜカーネルはそれを同じ状態に保つのですか?SIGCONT
シグナルを受信した瞬間に殺されたのはなぜですか?SIGTERM
シグナルが原因だった場合、プロセスが再開するまでどこに保管されていましたか?SIGSTOP
およびSIGKILL
は、プロセスでキャッチおよび処理できない2つのシグナルです。 SIGTSTP
は、SIGSTOP
に似ていますが、canをキャッチして処理する点が異なります。
SIGSTOP
およびSIGTSTP
信号は、SIGCONT
の準備ができているプロセスのトラックを停止します。そのプロセスにSIGTERM
を送信すると、プロセスは実行されていないため、終了するコードを実行できません。
(また、SIGTTIN
とSIGTTOU
があります。これらは、バックグラウンドジョブが端末への読み取りまたは書き込みを試みたときにTTYレイヤーによって生成された信号です。これらは、SIGTSTP
と同様に、キャッチできますが、プロセスを停止(中断)します。しかし、 mは、この回答の残りの部分では、これら2つを無視します。)
きみの CtrlZSIGTSTP
によってプロセスが特別に処理されていないように見えるrsyslogd
をプロセスに送信するので、SIGCONT
またはSIGKILL
を保留するだけでプロセスを一時停止します。
ここでの解決策は、プロセスがシグナルを受信して処理できるように、SIGCONT
の後にSIGTERM
を送信することです。
例:
sleep 999 &
# Assume we got PID 456 for this process
kill -TSTP 456 # Suspend the process (nicely)
kill -TERM 456 # Terminate the process (nicely). Nothing happens
kill -CONT 456 # Continue the process so it can exit cleanly
GNU C Library のドキュメントはこれをかなりよく説明していると思います(私の強調表示):
プロセスが停止している間、
SIGKILL
シグナルと(明らかに)SIGCONT
シグナルを除いて、プロセスが続行されるまで、プロセスにシグナルを配信できません。シグナルは保留中としてマークされますが、プロセスが続行されるまで配信されません。SIGKILL
信号は常にプロセスの終了を引き起こし、ブロック、処理、または無視することはできません。SIGCONT
は無視できますが、常にプロセスに停止してもとにかく続行されます。SIGCONT
シグナルをプロセスに送信すると、そのプロセスの保留中の停止シグナルが破棄されます。同様に、プロセスの保留中のSIGCONT
シグナルは、停止シグナルを受信すると破棄されます
SIGTERM
は他のすべての signal と同じです それはキャッチできます プロセスによって。シグナルを受信すると、プロセスは特別なシグナルハンドラルーチンにジャンプします。 SIGTERM
の場合、デフォルトのアクションはプロセスを終了することですが、たとえば、エディタは、死ぬ前に開いているファイルのドラフトコピーを保存できるように、シグナルをキャッチしたい場合があります。プロセスが停止した場合、シグナルハンドラーを実行できませんが、プロセスが続行するまでシグナルは保留されたままになります。送信された信号のnumberは通常保存されないことに注意してください。
理論的には、システムは、プロセスにSIGTERM
のシグナルハンドラーがインストールされているかどうかを確認し、インストールされていない場合はすぐに終了できます。しかし(Gillesのコメントのとおり)POSIXは、SIGCONT
を介してプロセスが続行されるまでシグナルを保留するよう要求しています。