У меня есть скрипт perl с несколькими дочерними процессами (создан с использованием fork()). Каждый ребенок спит, затем выполняет некоторую обработку (несколько вызовов system()). Под окнами, когда я нажимаю Ctrl + C, я вижу, что сигнал был пойман, тогда скрипт ждет, когда дети закончатся, и после этого выйдет. Я хочу реплицировать это поведение в linux (catch sigint, позволить детям завершить и выйти из основного сценария/процесса).Подождите, пока дети завершатся, если родительский перехват SIGINT
Как подождать, пока все дети закончатся, прежде чем убить родителя? Возможно ли выйти из основного сценария/убить родителя, но разрешить ли дети заполняться в фоновом режиме?
Я нашел Child process receives parent's SIGINT, и кажется, что SIGINT распространяется на детей (группа процессов), поэтому, чтобы этого избежать, мне пришлось бы установить ребенка в другую группу процессов.
$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, но цикл не приостановлена, создаются таким образом, новые дочерние процессы и родитель не умирает.
# I used my $parentPid = $$; (before the for loop) to get the parent pid.
if ($$ = $parentPid){
foreach $var (@pids) {
$pid = waitpid($var ,0);
}
EDIT:
Пытался установки детского SIGINT обработчика в игнор, и она работает, как ожидалось. В родительском обработчике я:
$SIG{'INT'} = sub {
print "Caught Ctrl+C by $$\n";
# while($result != -1){
# $result = wait();
#}
die "Stopping...";
};
а) Если включить строки комментариев сценарий ждет детей, чтобы закончить, а затем завершает свою работу.
б) Но если я комментирую линии «ждать» Я предполагаю, что это работает как это
- выходов сценария и родительский процесс завершается
- дети продолжают работать в фоновом режиме и дисплей «Выход из дочернего» сообщения, как ожидалось до выхода.
Я понимаю а) случай, но как работает б), объясните, почему это не порождает процессы зомби?
Да, моя ошибка с «==», теперь родительские выходы, и я получаю сообщения «Выход из ребенка», но сразу же, возможно, процесс сна у детей завершается, а остальная часть кода продолжается ? Я бы хотел, чтобы они спали, как указано ... И в отношении ожидания ... я должен использовать wait() - это будет ждать всех детей? –
Да, сигналы прерывают спящий режим, поэтому вы должны установить обработчик 'SIGINT' для игнорирования в дочерних элементах (' $ SIG {INT} = 'IGNORE'') –
Пробовал IGNORE для дочерних процессов, и он работает, но я до сих пор неясно о «ожидании». Посмотрите на edit –