linux 系统($command)调用如何在命令仍在运行的情况下返回0退出代码?

cetgtptt  于 2023-08-03  发布在  Linux
关注(0)|答案(2)|浏览(108)

下面的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线程。

0dxa2lsx

0dxa2lsx1#

这个systemfork之后的父进程†中运行,而子进程立即福尔斯。由于@pids被写入到其中一个进程 *(父进程)中,因此另一个进程(子进程)不会看到父进程变量的变化;它自己的@pids保持在if拆分进程之前的状态。‡因此,由于 its@pids是空的,所以子进程只是通过那个循环。
然后,在这个子进程中,通过空循环,右移(>>)是在一个未定义的值上完成的($return_code还没有被赋值)-- * 如果你有use warnings;在 * 上,你会得到一个警告--结果被转换为0,然后被赋值。然后,它被返回。
所以零是假的,没有意义。
if条件之前执行push @pids, $pid *,紧接着fork
另外,您需要退出其中一个进程--通常是if条件中的那个进程--否则您将有 * 两个 * 进程执行后面的所有代码。
另一种选择是为子进程添加一个else分支,子进程在该分支中退出。然后一切又恢复正常,因为父节点最终会到达它的@pids列表。
†通常通过以下方式选择分支

if ($pid == 0) {  # child process enters this branch, parent does not
    ...
}
# parent process drops right here, since its pid is not `0`

字符串
在这个问题中,情况正好相反,测试是否为true $pid--所以这里 * 父进程 * 进入分支,而子进程正好落在它的下面。当然,这也是可以的,讨论也适用。
‡当一个变量被写入到进程中时,进程会得到自己的副本。
但是让我们假设另一个进程(子进程)看到了@pids中的更改(在父进程中进行)。仍然会有一个问题--会有一个竞争条件,因为在父分支中的push @pids, $pidif分支中)发生之前,子分支很可能通过@pids * 进入循环。

w6lpcovy

w6lpcovy2#

我不知道你是如何从python调用perl的,但我假设你正在使用subprocess模块

import subprocess
process = subprocess.Popen("call perl script",  stdout=subprocess.PIPE, shell=True)
output = process.communicate()
print(output)

字符串

相关问题