但是當我做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腳本仍然STDOUT到xterm的屏幕。我該如何刪除它?
不要在孩子下面調用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。
改進了最後一個問題的答案。 – ikegami
首先我想感謝您的幫助! – user1539348
回到第一個問題。如果我們用ctrl + C來殺死子進程,如果它們仍然收到signit? 我把這個放在父$ SIG {INT} = sub {kill -9 $ pid}; ? 也是一個相關的問題如果一個孩子在父執行waitpid($ pid,0)之前已經完成了什麼?在多個孩子同時分岔的情況下(有一個循環),然後等待最後。 – user1539348