这个问题并不新鲜,https://www.perlmonks.org/?node_id=620645,但我没有找到我的问题的有效答案。简而言之,我想访问由系统、可执行文件或打开等函数创建的线程/进程的 PID。我使用打开函数my $pid = open my $fhOut, "| the command ", or die ...;
发现的一个,在 Linux 中,根据ps
命令的实际 PID 值是$pid + 2
,但在 wind32 中,实际的 PID 是一个负数(如 -1284(。在这两种情况下,打开函数返回的 PID 都与 $pid 不同!!
同样,my $pid = system 1, "command params"
返回的 pid 与操作系统中的 PID 不匹配。有人可以解释一下吗?退出从开放或系统函数调用的无限循环程序的正确方法是什么? 这是我的测试代码:
my $pid = fork();
if( $pid == 0 )
{
my $mimperf_pid = open my $cmd, "mimperf -C $db > results/mimperf/mimperf.log |" or die $!;
sleep(10);
print $mimperf_pid;
kill 'KILL', $mimperf_pid;
exit 0;
}
在此代码中,我试图杀死通过open
函数创建的线程($mimperf_pid(,但没有成功。
Windows不支持fork()
,所以Perl(很差(使用线程模拟它。这些虚拟进程具有负 PID。如果可以的话,你应该避免在Windows上fork()
,如果没有别的,就使用线程。
不过,这与你的问题无关。虽然fork
返回的 PID 为负数,但open
返回的 PID 不是负数。
一般应避免两参数open
,所以
open my $cmd, "foo bar |"
相当于
open my $cmd, "-|", "foo bar"
这相当于
open my $cmd, "-|", "cmd", "/x", "/c", "foo bar"
您正在启动一个 shell 来执行 shell 命令,open
返回的是 shell 的 PID。
system 1, $shell_cmd
也是如此。
这意味着 Ctrl-Break 信号正在发送到外壳。(这就是Perl代替不存在的SIGKILL发送的内容。
现在,我没有mimperf
所以我使用了一个替代程序而不是mimperf
(perl
(,它收到了 Ctrl-Break 信号以及 shell。因此,如果mimperf
没有退出,也许是因为它没有响应 Ctrl-Break?
如果你想避开外壳,你需要自己做输出重定向。为此,我推荐IPC::Run。它也处理超时。
use IPC::Run qw( run );
run [ "mimperf", "-C", $db ],
">", "results/mimperf/mimperf.log",
timeout(10);