Ткань должна вам помочь. В этом сервисе есть багтрекер, платформа для тестирования, аналитические сервисы и многое другое.
Используйте setsid , чтобы сделать ваш процесс новым лидером группы. Затем вы можете отправить уничтожение идентификатору группы и уничтожить все процессы, принадлежащие этой группе. Все процессы, которые вы порождаете из процесса лидера, наследуют идентификатор группы и принадлежат к вашей недавно созданной группе. Таким образом, отправка убийства в группу убьет их всех. Единственная хитрость заключается в том, что для того, чтобы иметь возможность использовать setsid, вы должны закрыть свой стандарт на входе и выходе, так как это требование для setsid.
use strict;
use warnings;
setpgrp $$, 0;
system("sleep.pl");
END {kill 15, -$$}
Но если вам нужен такой подход, вы делаете что-то не так. Вы не должны этого делать. Вместо этого запустите и уничтожьте ваш процесс kill правильно.
$ perl -e 'system("sleep 100")' &
[1] 11928
$ ps f
PID TTY STAT TIME COMMAND
4564 pts/1 Ss 0:01 /bin/bash
11928 pts/1 S 0:00 \_ perl -e system("sleep 100")
11929 pts/1 S 0:00 | \_ sleep 100
11936 pts/1 R+ 0:00 \_ ps f
$ kill %1
[1]+ Terminated perl -e 'system("sleep 100")'
$ ps f
PID TTY STAT TIME COMMAND
4564 pts/1 Rs 0:01 /bin/bash
11949 pts/1 R+ 0:00 \_ ps f
Как это работает? Shell (bash в моем случае) должен установить ваш процесс в качестве лидера группы, если вы работаете в фоновом режиме. Тогда, если вы используете синтаксис kill%?
, оболочка правильно убивает группу. Сравните это:
$ perl -e 'system("sleep 100")' &
[1] 12109
$ ps f
PID TTY STAT TIME COMMAND
4564 pts/1 Rs 0:01 /bin/bash
12109 pts/1 S 0:00 \_ perl -e system("sleep 100")
12113 pts/1 S 0:00 | \_ sleep 100
12114 pts/1 R+ 0:00 \_ ps f
$ kill 12109
[1]+ Terminated perl -e 'system("sleep 100")'
$ ps f
PID TTY STAT TIME COMMAND
4564 pts/1 Ss 0:01 /bin/bash
12124 pts/1 R+ 0:00 \_ ps f
12113 pts/1 S 0:00 sleep 100
Но kill%?
работает следующим образом:
$ perl -e 'system("sleep 100")' &
[1] 12126
$ ps f
PID TTY STAT TIME COMMAND
4564 pts/1 Rs 0:01 /bin/bash
12126 pts/1 S 0:00 \_ perl -e system("sleep 100")
12127 pts/1 S 0:00 | \_ sleep 100
12128 pts/1 R+ 0:00 \_ ps f
$ kill -12126
[1]+ Terminated perl -e 'system("sleep 100")'
$ ps f
PID TTY STAT TIME COMMAND
4564 pts/1 Ss 0:01 /bin/bash
12130 pts/1 R+ 0:00 \_ ps f
Ваш вопрос действительно является конкретным примером более общего вопроса "как сделать так, чтобы ребенок умирал, когда умирает родитель". Без этого просто не обойтись. В system() нет ничего особенного; она просто форкает дочерний процесс и ждет его завершения.
system() выглядит примерно так:
sub system
{
my $kidpid = fork;
if ( $kidpid )
{
waitpid $kidpid;
# parent process blocks here waiting for the child process to return
}
else
{
exec( @_ );
}
}
Убийство группы процессов - ваш единственный выход.