我正在运行一个Perl脚本,该脚本在内部启动bsub作业。当我根据组ID运行perl脚本时,我想杀死在unix终端中按下控件c时,此perl脚本启动的所有作业。
请告知。
感谢与问候 阿姆鲁莎
编辑:从评论复制的代码
my $command = "bsub -q normal -g GROUPID <command>";
system($command);
答案 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 post和this post中有一些搜寻过程的示例。