Какие сигналы должен передавать скрипт-обертка подпрограмме? - PullRequest
1 голос
/ 14 февраля 2009

Если у меня есть сценарий, который является оболочкой для другой программы (например, оболочка для демонизатора или оболочка для mathematica ), иногда полезно отлавливать сигналы в оболочке запрограммировать и передать их в подпрограмму. Например, вот некоторый код Perl для обработки сигнала INT (прерывания), так что если вы выполняете ctrl-C после запуска оболочки, подпрограмма также прерывается:

my $subprogram = "foo args";
my $pid = open(F, "$subprogram |") or die "Can't open pipe from $subprogram: $!";
$SIG{INT} = sub { kill('INT', $pid); 
                  close(F); 
                  die "Passed along INT signal and now aborting.\n"; };
print while(<F>);
close(F);

Из [всех возможных сигналов] (http://en.wikipedia.org/wiki/Signal_(computing), которые может обработать программа, какие из них должен передать скрипт-обертка?
Что-нибудь еще, что должна сделать хорошая обертка?

РЕДАКТИРОВАТЬ: Первоначально этот вопрос спрашивал, как передать все возможные сигналы. Благодаря первоначальным ответам я узнал, что это не правильный вопрос.

РЕДАКТИРОВАТЬ: я выяснил, что бросило меня на петлю здесь. Mathematica, очевидно, отрывается от своего родительского процесса. Поэтому я должен явно передавать различные сигналы завершения:

$SIG{INT} =  sub { kill('INT', $pid); };  # pass along SIGINT (eg, ctrl-C)
$SIG{TERM} = sub { kill('TERM', $pid); }; # pass along SIGTERM (kill's default)
$SIG{QUIT} = sub { kill('QUIT', $pid); }; # pass along SIGQUIT
$SIG{ABRT} = sub { kill('ABRT', $pid); }; # pass along SIGABRT
$SIG{HUP} =  sub { kill('HUP', $pid); };  # pass along SIGHUP

Как правило, в этом нет необходимости, поскольку дочерние процессы автоматически передают эти сигналы (спасибо за ответы, которые прямо об этом говорят!). Так что теперь мне интересно, почему (и как) Mathematica отрывается от себя ...

Ответы [ 4 ]

2 голосов
/ 14 февраля 2009

Отсутствует.

Сигналы, которые вы можете генерировать на клавиатуре, все равно отправляются дочернему процессу, если только ребенок не предпримет шаги, чтобы этого избежать (в этом случае, кто вы такой, чтобы вмешиваться).

Другие сигналы, которые могут уничтожить родительский процесс, обычно приводят к исчезновению дочернего элемента при следующей записи в канал, который был закрыт при смерти родительского процесса.

Итак, если у вас нет оснований полагать, что дочерний процесс неправильно обрабатывает сигналы, я бы не стал беспокоиться о передаче каких-либо сигналов ребенку. И если ребенок неправильно управляет сигналами, возможно, вам следует исправить ребенка, а не взламывать родителя.

2 голосов
/ 14 февраля 2009

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

ETA: сигналы остановки и перезапуска отправляются всей группе процессов. Если это то, что вам нужно: просто убедитесь, что ваш дочерний процесс является частью этой группы процессов (по умолчанию это AFAIK).

ETA2: Если mathematica действительно отсоединяется (что можно сделать с помощью setsid() и setpgid()), это означает, что она явно не хочет получать такие сигналы, поэтому вы не должны отправлять их: вероятно, они не будут обрабатываться в любом случае. 1007 *

2 голосов
/ 14 февраля 2009

Есть много сигналов, которые было бы опасно просто «пройти» таким образом. «Человек 7 сигнал» и посмотрите на такие вещи, как SIGPIPE, SIGILL, SIGCHILD и т. д. Очень вероятно, что вы просто не хотите трогать этих парней.

Итак, реальный вопрос становится следующим: какое поведение вы ищете? Бьюсь об заклад, все, что вы действительно хотите, это чтобы SIGINT & SIGCONT были переданы ребенку. Подпрограмма работает с другими сигналами, такими как HUP, USR1 или USR2?

Полагаю, вы действительно просто заинтересованы в SIGINT & SIGCONT, а остальные (то есть SIGSEGV, SIGKILL и т. Д.) Позаботятся о себе, так как завершение родительского процесса также очистит ребенка.

Да, и, кстати, ваш пример:

print while(<F>);

Хорошо, и если родительский процесс perl приостановлен, он не продолжит чтение из F, как только этот канал заполнится, ваша подпрограмма будет блокировать запись в стандартный вывод, что, вероятно, в значительной степени соответствует желаемому поведению.

Для более интересных мыслей, взгляните на man bash и встроенную ловушку, чтобы увидеть, что разработчики оболочки сделали, чтобы помочь в этой проблеме.

1 голос
/ 14 февраля 2009

Вы можете получить список всех сигналов с помощью keys %SIG. Таким образом, чтобы передать их всем, вы устанавливаете обработчики для отправки сигнала ID дочернего процесса:

for my $signal (keys %SIG) {
    $SIG{$signal} = sub { kill($signal, $child_pid); };
}

Возможно, вы захотите локализовать %SIG.

Не то чтобы я говорил, что это хорошая идея, но вот как это сделать.

...