我知道应该避免在perl中使用shell命令,但这是我写的一个快速脚本来测试失败 - 它不是永久性的。
这里的目标是分叉一个孩子并让它对数据库运行一些查询。然后在10秒后(这是孩子正常退出的充足时间),父运行ps
以查看孩子是否仍然存在(如果是,它挂起),查看{{1}中的返回码然后决定做什么。代码:
$?
我有没有看到隐藏的竞争条件?
答案 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
之间时,会发生上述竞争条件。