1

I am running a perl script which internally launches bsub jobs . I wanted to kill all jobs launched by this perl script when control c is pressed in unix terminal when i run the perl script based on the group id .

Please advise.

Thanks & Regards amrutha


Edit: code copied from a comment

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

system($command); 
zdim
  • 64,580
  • 5
  • 52
  • 81
Chinnu
  • 45
  • 1
  • 6
  • Can send `kill` to whatever processes need be terminated from the signal handler (or use a module for process management). Can you show how you launch jobs and what they are? – zdim Jul 20 '18 at 05:22
  • I assign my $command = "bsub -q normal -g GROUPID "; system($command); – Chinnu Jul 20 '18 at 06:15
  • Thank you but please edit the question to add that to it. Further detail would be helpful as well. – zdim Jul 20 '18 at 07:57

1 Answers1

1

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.

zdim
  • 64,580
  • 5
  • 52
  • 81