Perl脚本可在按下控件c时停止bsub作业

时间:2018-07-20 04:50:55

标签: perl control-c

我正在运行一个Perl脚本,该脚本在内部启动bsub作业。当我根据组ID运行perl脚本时,我想杀死在unix终端中按下控件c时,此perl脚本启动的所有作业。

请告知。

感谢与问候 阿姆鲁莎


编辑:从评论复制的代码

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

system($command); 

1 个答案:

答案 0 :(得分:1)

尝试通过kill通过Ctrl-C从信号处理程序发送SIGTERM到进程组

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

这是否可行,以及可靠性如何,取决于这些工作是做什么的许多细节。

下面显示了一个流程如何(不知不觉地)躲避项目符号的示例,其中子流程更改了其流程组ID。这样做是为了向组发送信号的演示,但是随后还演示了向组发送信号的漏洞。

一个例子

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(将被分配),并在孩子中将其组ID设置为该孩子的{$$)。

由于分叉进程继承了处理程序,因此信号也必须在子级中处理。

几秒钟后按下Ctrl-C,输出为

Parent 10450 started 10451
        Child's process group: 10451
^CGot INT. Send TERM to group 10451
done

其中done在前一次打印后3秒钟被打印。 kid done永远不会来。

如果您希望父母也终止,请在信号处理程序中添加exit等。

如上所述,这可能会失败,原因之一是孩子可以简单地更改其组。一种更可靠的方法是对可能触发的作业进行分类,然后在运行时找到其PID,以便终止它们。 Proc::ProcessTable是一个有用的工具。 this postthis post中有一些搜寻过程的示例。