这是一种可靠的杀死子进程的方法吗? [Perl的]

时间:2014-08-07 15:21:30

标签: perl fork

我知道应该避免在perl中使用shell命令,但这是我写的一个快速脚本来测试失败 - 它不是永久性的。

这里的目标是分叉一个孩子并让它对数据库运行一些查询。然后在10秒后(这是孩子正常退出的充足时间),父运行ps以查看孩子是否仍然存在(如果是,它挂起),查看{{1}中的返回码然后决定做什么。代码:

$?

我有没有看到隐藏的竞争条件?

2 个答案:

答案 0 :(得分:3)

你已经说过了; shell应该避免,因为它更复杂,更容易出错,并且需要正确的输出处理($return == 0没有做你想做的事。)

my $is_alive = kill(0, $pid);
if ($is_alive) { kill child ... }

答案 1 :(得分:1)

尽可能少地睡觉,而不是无条件地等待10秒。

my %children;
local $SIG{CHLD} = sub {
   while (1) {
      my $pid = waitpid(-1, WNOHANG);
      last if $pid < 1;
      $children{$pid} = $?;
   }
};

my $pid = fork();
if ($pid == 0) {
   ...
   exit();
}

my $end_time = time + 10;
while (!defined($children{$pid})) {
   my $sleep_time = $end_time - time;
   last if $sleep_time <= 0;

   #sleep($sleep_time);
   sleep(1);   # Mitigate race condition.
}

my $killkill;
while (!defined($children{$pid})) {
   kill($killkill++ ? 'TERM' : 'KILL', $pid);
   sleep(2);
}

当信号进入defined($children{$pid})检查和系统调用sleep之间时,会发生上述竞争条件。