Скрипт Perl для остановки работы bsub при нажатии элемента управления c

Я запускаю Perl-скрипт, который внутренне запускает задания bsub. Я хотел убить все задания, запускаемые этим сценарием perl, когда в терминале unix нажимается элемент управления c, когда я запускаю сценарий perl на основе идентификатора группы.

Пожалуйста, порекомендуйте.

Спасибо и привет Amrutha


Изменить: код скопирован из комментария

my $command = "bsub -q normal -g GROUPID <command>";

system($command); 

1 ответ

Попробуй отправить SIGTERM через kill в группу процессов из обработчика сигнала для Ctrl-C

$SIG{INT} = sub { kill 15, -$gpid };  # $gpid used in bsub command

Будет ли это работать и насколько надежно, зависит от многих деталей того, чем занимаются эти рабочие места.

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

Пример

use warnings;
use strict;
use feature 'say';

my $pid;

$SIG{INT} = sub { 
    say "Got $_[0]. Send TERM to process group with $pid"; 
    kill 15, -$pid;
}; 

$pid = fork // die "Can't fork: $!";

if ($pid == 0) {
    $SIG{INT} = 'IGNORE';
    setpgrp 0, $$;
    say "\tChild's process group: ", getpgrp;
    sleep 10; 
    say "\tkid done"; 
    exit;
}; 

say "Parent $$ started $pid";

sleep 5; 
sleep 3;   # return to sleep after signal is handled

say "done";

когда kill отправляется на отрицательный PID (или с отрицательным сигналом) и отправляется в эту группу процессов. Здесь я использую ребенка $pid (быть назначенным) и в дочернем элементе установить его идентификатор группы к этому ($$).

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

С нажатой клавишей Ctrl-C через несколько секунд, вывод

Родитель 10450 начал 10451
        Детская процессная группа: 10451
^CGot INT. Отправьте ТЕРМИН в группу 10451
сделанный

где done печатается через 3 секунды после предыдущих отпечатков. kid done никогда не приходит

Если вы хотите, чтобы родитель также прекратил, добавьте exit или такой к обработчику сигнала.

Как уже отмечалось, это может потерпеть неудачу, с одной стороны, поскольку ребенок может просто изменить свою группу. Более надежным способом было бы каталогизировать задания, которые могут быть запущены, а затем найти их PID во время выполнения, чтобы завершить их. Полезный инструмент для этого - Proc:: ProcessTable. Некоторые примеры выслеживания процессов находятся в этом посте и этом посте.

Другие вопросы по тегам