如果父母拦截了SIGINT,请等待孩子完成 [英] Wait for children to complete if parent intercepts SIGINT
问题描述
我有一个带有多个子进程的perl脚本(使用fork()创建).每个孩子睡觉后进行一些处理(几个system()调用).在Windows下,当我按Ctrl + C时,我看到信号已捕获,然后脚本等待子进程完成,然后退出.我想在linux中复制此行为(catch sigint,让孩子完成并退出主脚本/进程).
I have a perl script with multiple child processes (created using fork()). Each child sleeps then does some processing (several system() calls). Under windows when I hit Ctrl+C I see that the signal was caught , then the script waits for the children to complete and after this exits. I want to replicate this behaviour in linux (catch sigint , let the children complete and exit the main script/process ).
在杀死父母之前,我该如何等待所有孩子完成?是否可以退出主脚本/杀死父脚本,但让孩子在后台完成?
How do I wait for all children to complete before killing the parent ? Is it possible to exit the main script / kill the parent , but let the children complete in the background ?
我发现子进程接收了父级的SIGINT ,并且似乎SIGINT传播到了孩子(流程组),因此要避免这种情况,我必须将孩子设置在不同的流程组中.
I found Child process receives parent's SIGINT , and it seems SIGINT is propagated to the children (the process group) , so to avoid this I'd have to set the child in a different process group.
$SIG{'INT'} = sub {
print "Caught Ctrl+C\n";
die "Stopping...";
};
++$|;
print "Start\n";
for($i=0; $i < 500; $i++) {
sleep 3;
$childPid = fork(); #fork a process
if($childPid == 0){
print "Child $i...\n";
sleep 10;
system("echo finishing");
print "Exit child $i\n";
exit;
}
}
我还尝试将其包含在SIGINT处理块中,但是for循环没有暂停,因此创建了新的子进程,并且父进程不会死.
I also tried to include this in the SIGINT processing block , but the for loop isn't paused , so new child processes are created and parent doesn't die.
# I used my $parentPid = $$; (before the for loop) to get the parent pid.
if ($$ = $parentPid){
foreach $var (@pids) {
$pid = waitpid($var ,0);
}
尝试将子SIGINT处理程序设置为IGNORE,并且按预期工作.在父处理程序中:
Tried setting the child SIGINT handler to IGNORE and it works as expected. In the parent handler I do :
$SIG{'INT'} = sub {
print "Caught Ctrl+C by $$\n";
# while($result != -1){
# $result = wait();
#}
die "Stopping...";
};
a):如果包含注释行,脚本将等待子级完成然后退出.
a) If include the commented lines the script waits for the children to complete and then exits.
b)但是,如果我评论"wait"行,我认为它的工作原理是这样的
b) But if I comment the "wait" lines I assume it works like this
- 脚本退出,父进程终止
- 孩子继续在后台运行,并在退出前按预期显示退出孩子"消息.
我了解a)的情况,但b)的情况如何工作,请解释为什么这不生成僵尸进程?
I understand the a) case but how does the b) case work, please explain why doesn't this generate zombie processes ?
推荐答案
在Windows下,当我按Ctrl + C时,我看到信号已捕获,然后脚本等待子项完成,然后退出.
Under windows when I hit Ctrl+C I see that the signal was caught , then the script waits for the children to complete and after this exits.
我认为这是伪叉实现的副作用.
I think this is a side-effect of the psuedo-fork implementation.
在杀死父母之前,我如何等待所有孩子完成?
How do I wait for all children to complete before killing the parent ?
最简单的方法是忽略子代中的SIGINT
和父代SIGINT
处理程序中的wait
/waitpid
.
The easiest way is to ignore the SIGINT
In the children, and wait
/waitpid
in the parents SIGINT
handler.
我还尝试将其包含在SIGINT处理块中,但是for循环没有暂停,因此创建了新的子进程,并且父进程不会死.
I also tried to include this in the SIGINT processing block , but the for loop isn't paused , so new child processes are created and parent doesn't die.
我认为您的意思是$$ == $parentPid
(比较而不是赋值).另外,如果您仍在等待所有孩子,则指定等待的孩子并不是真正有用.
I think you meant $$ == $parentPid
(comparison instead of assignment). Also, it's not really useful to specify which child you're waiting for if you're waiting for all of them anyway.
这篇关于如果父母拦截了SIGINT,请等待孩子完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!