web-dev-qa-db-ja.com

SIGTERMでSIGSTOPされたプロセスを強制終了できないのはなぜですか?保留中のシグナルはどこに保存されますか?

私はDebianストレッチ(systemd)を使用しています。 /usr/sbin/rsyslogd -nを使用してフォアグラウンドでrsyslogデーモンを実行していて、 Ctrl+Z それを止める。プロセスの状態がTl(停止、スレッド化)に変わりました。プロセスに複数のkill -15 <pid>コマンドを発行しましたが、プロセスの状態は同じでした:Tlfgを実行すると、死亡しました。 3つの質問があります。

  • SIGSTOP- edプロセスがSIGTERMに応答しないのはなぜですか?なぜカーネルはそれを同じ状態に保つのですか?
  • SIGCONTシグナルを受信した瞬間に殺されたのはなぜですか?
  • 以前のSIGTERMシグナルが原因だった場合、プロセスが再開するまでどこに保管されていましたか?
24
nohup

SIGSTOPおよびSIGKILLは、プロセスでキャッチおよび処理できない2つのシグナルです。 SIGTSTPは、SIGSTOPに似ていますが、canをキャッチして処理する点が異なります。

SIGSTOPおよびSIGTSTP信号は、SIGCONTの準備ができているプロセスのトラックを停止します。そのプロセスにSIGTERMを送信すると、プロセスは実行されていないため、終了するコードを実行できません。

(また、SIGTTINSIGTTOUがあります。これらは、バックグラウンドジョブが端末への読み取りまたは書き込みを試みたときに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シグナルは、停止シグナルを受信すると破棄されます

42
roaima

SIGTERMは他のすべての signal と同じです それはキャッチできます プロセスによって。シグナルを受信すると、プロセスは特別なシグナルハンドラルーチンにジャンプします。 SIGTERMの場合、デフォルトのアクションはプロセスを終了することですが、たとえば、エディタは、死ぬ前に開いているファイルのドラフトコピーを保存できるように、シグナルをキャッチしたい場合があります。プロセスが停止した場合、シグナルハンドラーを実行できませんが、プロセスが続行するまでシグナルは保留されたままになります。送信された信号のnumberは通常保存されないことに注意してください。

理論的には、システムは、プロセスにSIGTERMのシグナルハンドラーがインストールされているかどうかを確認し、インストールされていない場合はすぐに終了できます。しかし(Gillesのコメントのとおり)POSIXは、SIGCONTを介してプロセスが続行されるまでシグナルを保留するよう要求しています。

9
ilkkachu