しかし、親を殺すために ctrl+c を実行すると、シグナルは子によって無視されます。
信号は、親と子の両方に送信されます。
$ perl -E'
if (my $pid = fork()) {
local $SIG{INT} = sub { say "Parent got SIGINT" };
sleep;
waitpid($pid, 0);
} else {
local $SIG{INT} = sub { say "Child got SIGINT" };
sleep;
}
'
^CParent got SIGINT
Child got SIGINT
その子がそれを無視する場合、それは新しいセッションを開始したか、明示的に無視したためです。
.sh スクリプトを実行する子プロセスは、xterm の画面に対して STDOUT のままです。どうすればこれを削除できますか?
を呼び出す前に、子で次のことを行いますexec
。
open(STDOUT, '>', '/dev/null');
open(STDERR, '>', '/dev/null');
実際、私はopen3
いくつかのエラーチェックを取得するために使用します。
open(local *CHILD_STDIN, '<', '/dev/null') or die $!;
open(local *CHILD_STDOUT, '>', '/dev/null') or die $!;
my $pid = open3(
'<&CHILD_STDIN',
'>&CHILD_STDOUT',
'>&CHILD_STDOUT',
'shell.sh', 'args',
);
親プロセス (perl スクリプト) は、子 (.sh スクリプト) を待機しません。それで、子供がゾンビになることについてたくさん読んだことがありますか???
親が終了したとき、または親が終了した後に子が終了した場合、子は自動的にリープされます。
$ perl -e'
for (1..3) {
exec(perl => (-e => 1)) if !fork;
}
sleep 1;
system("ps");
' ; ps
PID TTY TIME CMD
26683 pts/13 00:00:00 bash
26775 pts/13 00:00:00 perl
26776 pts/13 00:00:00 perl <defunct> <-- zombie
26777 pts/13 00:00:00 perl <defunct> <-- zombie
26778 pts/13 00:00:00 perl <defunct> <-- zombie
26779 pts/13 00:00:00 ps
PID TTY TIME CMD
26683 pts/13 00:00:00 bash
26780 pts/13 00:00:00 ps
<-- all gone
子が終了する前に親が終了しても、問題はありません。
子が終了した直後に親が終了しても、問題はありません。
子が終了してから親が終了するまでに時間がかかる場合は、それらを取得する必要があります。wait
またはwaitpid
(おそらくハンドラーから)を使用してそれを行うかSIGCHLD
、または を使用してそれらを自動的にリープさせることができます$SIG{CHLD} = 'IGNORE';
。perlipcを参照してください。