下面的perl代码是通过Python脚本运行的。
my $pid = fork;
my @pids;
if ($pid) {
push(@pids, $pid);
$return_code = system($command);
}
foreach my $pid (@pids) {
waitpid($pid, 0);
}
$return_code = $return_code >> 8;
return $return_code;
字符串
即使$命令在接下来的5分钟内运行,$return_code也为0。
这种情况只发生过一次。我后来无法复制它。有人能确定是什么原因导致了这个问题吗?$命令将调用多个Perl线程。
2条答案
按热度按时间0dxa2lsx1#
这个
system
在fork
之后的父进程†中运行,而子进程立即福尔斯。由于@pids
被写入到其中一个进程 *(父进程)中,因此另一个进程(子进程)不会看到父进程变量的变化;它自己的@pids
保持在if
拆分进程之前的状态。‡因此,由于 its@pids
是空的,所以子进程只是通过那个循环。然后,在这个子进程中,通过空循环,右移(
>>
)是在一个未定义的值上完成的($return_code
还没有被赋值)-- * 如果你有use warnings;
在 * 上,你会得到一个警告--结果被转换为0
,然后被赋值。然后,它被返回。所以零是假的,没有意义。
在
if
条件之前执行push @pids, $pid
*,紧接着fork
。另外,您需要退出其中一个进程--通常是
if
条件中的那个进程--否则您将有 * 两个 * 进程执行后面的所有代码。另一种选择是为子进程添加一个
else
分支,子进程在该分支中退出。然后一切又恢复正常,因为父节点最终会到达它的@pids
列表。†通常通过以下方式选择分支
字符串
在这个问题中,情况正好相反,测试是否为true
$pid
--所以这里 * 父进程 * 进入分支,而子进程正好落在它的下面。当然,这也是可以的,讨论也适用。‡当一个变量被写入到进程中时,进程会得到自己的副本。
但是让我们假设另一个进程(子进程)看到了
@pids
中的更改(在父进程中进行)。仍然会有一个问题--会有一个竞争条件,因为在父分支中的push @pids, $pid
(if
分支中)发生之前,子分支很可能通过@pids
* 进入循环。w6lpcovy2#
我不知道你是如何从python调用perl的,但我假设你正在使用subprocess模块
字符串