Как может я тайм-аут разветвленный процесс, который мог бы зависнуть?

Я пишу сценарий Perl, который запишет некоторые исходные данные и отправит те исходные данные во внешнюю программу. Существует маленький, но ненулевой шанс, что эта программа зависнет, и я хочу привести к таймауту ее:

my $pid = fork;
if ($pid > 0){
    eval{
        local $SIG{ALRM} = sub { die "TIMEOUT!"};
        alarm $num_secs_to_timeout;
        waitpid($pid, 0);
        alarm 0;
    };
}
elsif ($pid == 0){
    exec('echo blahblah | program_of_interest');
    exit(0);
}

Как есть теперь, после $num_secs_to_timeout, program_of_interest все еще сохраняется. Я пытался уничтожить его в анонимной подпрограмме для $SIG{ALRM} следующим образом:

local $SIG{ALRM} = sub{kill 9, $pid; die "TIMEOUT!"}

но это ничего не делает. program_of_interest все еще сохраняется. Как я иду об уничтожении этого процесса?

7
задан brian d foy 27 December 2009 в 07:58
поделиться

3 ответа

Я смог успешно убить свой exec()ed процесс, убив группу процесса , как показано в ответе на вопрос In perl, убивая ребенка и его детей, когда ребенок был создан с помощью open. Я модифицировал свой код следующим образом:

my $pid = fork;
if ($pid > 0){
    eval{
        local $SIG{ALRM} = sub {kill 9, -$PID; die "TIMEOUT!"};
        alarm $num_secs_to_timeout;
        waitpid($pid, 0);
        alarm 0;
    };
}
elsif ($pid == 0){
    setpgrp(0,0);
    exec('echo blahblah | program_of_interest');
    exit(0);
}

После таймаута успешно убивается программа_of_interest.

8
ответ дан 6 December 2019 в 15:23
поделиться

Хммм ваш код работает для меня , после некоторых незначительных модификаций, которые, как я полагаю, внесены вами, чтобы превратить код в общий пример.

Так что оставляет мне две идеи:

  1. Вы устранили проблему, когда создали пример кода - попробуйте создать небольшой образец, который действительно работает (мне пришлось изменить 'program_of_interest' и $ num_secs_to_timeout на реальные значения, чтобы проверить это). Убедитесь, что в образце та же проблема.
  2. Это как-то связано с запущенной вами program_of_interest - насколько я знаю, вы не можете замаскировать kill 9, но, возможно, что-то происходит. Вы пробовали протестировать свой код с помощью действительно простого скрипта. Я создал один для тестирования, который проходит while (1) {print "hi \ n"; сон 1; }
  3. Что-то еще .
2
ответ дан 6 December 2019 в 15:23
поделиться

Единственный способ игнорировать SIGKILL - это если процесс застрял в системном вызове, который невозможно прервать. Проверьте состояние зависшего процесса (с помощью ps aux ), если состояние - D, то процесс не может быть остановлен.

Вы также можете проверить, что функция вызывается, выводя что-то из этого.

1
ответ дан 6 December 2019 в 15:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: