Try to send SIGTERM
via kill to the process group from the signal handler for Ctrl-C
$SIG{INT} = sub { kill 15, -$gpid }; # $gpid used in bsub command
Whether this will work, and how reliably, depends on many details of what those jobs are and do.
An example of how a process can (unknowingly) dodge the bullet is seen below, where the child process changes its process group ID. It does this for a demo of signalling the group but then that also demonstrates a loophole in signalling the group.
An example
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";
When kill
is sent to a negated PID (or with a negative signal) it goes to that process group. Here I use the child's $pid
(to be assigned) and in the child set its group id to that ($$
).
The signal has to be dealt with in the child as well since the forked process inherits the handler.
With Ctrl-C pressed after a few seconds the output is
Parent 10450 started 10451
Child's process group: 10451
^CGot INT. Send TERM to group 10451
done
where done
is printed 3 seconds after the previous prints. The kid done
never comes.
If you want the parent to terminate as well add an exit
or such to the signal handler.
As noted, this may fail, for one thing since the child can simply change its group. A more reliable way would be to catalog jobs that may get triggered and then find their PIDs at runtime, so to terminate them. A useful tool for this is Proc::ProcessTable. Some examples of hunting down processes are in this post and this post.