ターミナルエミュレータは、SIGKILLを受信した後、どのようにして子供を殺すことができますか?


12

私が理解していることから、SIGKILLは捕まえられません。これは、OSがプロセスを破壊する前に、プロセスがその子を殺す時間がないことを意味します。これは、シェルスクリプトで実証できます。

#! /bin/bash

trap : SIGTERM SIGINT SIGKILL # SIGKILL is pointless.

mplayer video.avi

SIGKILLで削除すると、mplayerが実行されたままになります。

$ kill -9 $pid

しかし、ターミナルエミュレータ(xterm、Terminalなど)を使用すると、子供が一緒に殺されてしまいます。これはどのように可能ですか?

$ mplayer

そしてそれを殺します:

$ kill -9 $terminal_pid

そして、mplayerは船に搭載されます。ターミナルエミュレータは何らかの理由でSIGKILLをキャッチしていますか?

回答:


11

によって開始されたプロセスxtermは、端末を制御するセッションリーダーになります。

ターミナルがなくなると、そのプロセスは自動的にSIGHUPシグナルを受信します(SIGCONTが後に続きます)。これは、CTRL-Cを押したときにプロセスがSIGINTを受信するのと同様の方法でカーネルによって送信されます。

さらに、シェルは、終了時に子の一部にSIGHUPを送信する場合があります(disownそれを無効にするシェルを参照してください)。


1
:セッションとセッションの指導者に関する情報についてはunix.stackexchange.com/questions/18166/...
ケビンコックス

+1 disown非常に便利です。
数学

1

あなたの質問はそれ自身に答えます。これは、これらのプロセスがターミナルエミュレータの下で子として実行されているために起こります。そのため、ターミナルエミュレータを強制終了し、その際に、すべての子プロセスを強制終了します(子は制御端末エミュレータと同じプロセスグループで実行されているため)。

たとえば、次を参照してください。

csb@darwin[~]$ ps fauwx | grep -A6 "xfce4-terminal" | awk '{ for (i = 2; i <= 9; i++) $i="" ; print $0 }' 
csb         0:32 xfce4-terminal --geometry=271x65 --display :0.0 --role=Terminal-0x1340050-2606-1351620352 --show-menubar --show-borders --hide-toolbars --working-directory /home/csb --tab --working-directory /home/csb
csb         0:00 \_ gnome-pty-helper
csb         0:00 \_ bash
csb         0:00 | 
                  \_ ssh [redacted]
csb         0:00 \_ bash
csb         0:00 \_ ps fauwx
csb         0:00 \_ grep --color=auto -A6 xfce4-terminal
csb         0:00 \_ awk { for (i = 2; i <= 9; i++) $i="" ; print $0 }

これらのプロセスはすべて「xfce4-terminal」プロセスの下で実行されているため、そのプロセスを強制終了すると、プロセスグループ内のすべての子プロセスが自動的に強制終了されます。たとえば、ターミナルエミュレータウィンドウを終了する場合と同じ必ずSSH接続を切断してください。

シェルなどのプログラムは、通常、関連する子プロセスをグループに入れる新しいプロセスグループを作成します。各ジョブはプロセスグループです。カーネルの外部では、シェルはkillpgシステムコールを使用してジョブのプロセスグループにシグナルを送信し、プロセスグループ内のすべてのプロセスにシグナルを送信することにより、ジョブを操作します。


3
-1:親を殺しても、子は殺されませ
-camh

2
シェルなどのプログラムは新しいプロセスグループを作成し、通常は関連する子プロセスをグループに配置します。各ジョブはプロセスグループです。カーネルの外部では、シェルはkillpgシステムコールを使用してジョブのプロセスグループにシグナルを送信し、プロセスグループ内のすべてのプロセスにシグナルを送信することにより、ジョブを操作します。
チャールズボイド

2
@CharlesBoydそのコメントはあなたの答えの一部であるべきです。
ヨルダン

4
@CharlesBoyd:それを答えに追加すると、-1ではなく+1が与えられます。現在、あなたの答えは、親プロセスが殺されたときに子プロセスが殺されたように見えます(BTW、そのプロセスベースではなく、セッションベース)。
-camh

@CharlesBoyd私はそれを理解していますが、質問のポイントは、SIGKILLを受信したときに、「シグナルを送信することによってジョブを操作する方法」です。killpgその時点でシステムコールを使用する方法はありません。
ケビンコックス

0

第一に、端末が殺されても生き残るmplayerを再現できません。 xterm

それが死ぬ理由は、それが親の死からSIGHUPを得るためです。


私はそれを言ったことは一度もありません。死ぬと言いましたが、台本の中にあり、それが殺されても生き残ります。
ケビンコックス

私にとっては、スクリプトで生き残れません。
タンブルウィード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.