但是当我执行 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
or waitpid
(可能来自SIGCHLD
handler),或者你可以使用以下命令自动收获它们$SIG{CHLD} = 'IGNORE';
. See perlipc.