gpt4 book ai didi

perl - 如何让waitpid阻塞循环

转载 作者:行者123 更新时间:2023-12-03 16:11:07 25 4
gpt4 key购买 nike

以下代码运行 2 个 child ,他们将等待 10 秒并终止。父进程坐在一个循环中,等待子进程终止:

#!/usr/bin/perl

use strict;
use warnings;
use POSIX ":sys_wait_h";

sub func
# {{{
{
my $i = shift;
print "$i started\n";
$| = 1;
sleep(10);
print "$i finished\n";
}
# }}}

my $n = 2;
my @children_pids;

for (my $i = 0; $i < $n; $i++) {
if ((my $pid = fork()) == 0) {
func($i);
exit(0);
} else {
$children_pids[$i] = $pid;
}
}

my $stillWaiting;
do {
$stillWaiting = 0;
for (my $i = 0; $i < $n; ++$i) {
if ($children_pids[$i] > 0)
{
if (waitpid($children_pids[$i], WNOHANG) != 0) {
# Child is done
print "child done\n";
$children_pids[$i] = 0;
} else {
# Still waiting on this child
#print "waiting\n";
$stillWaiting = 1;
}
}
#Give up timeslice and prevent hard loop: this may not work on all flavors of Unix
sleep(0);
}
} while ($stillWaiting);

print "parent finished\n";

该代码基于此答案: Multiple fork() Concurrency

它工作正常,但父循环正在消耗处理器时间。 top命令给出了这个:

enter image description here

Here答案说:

As an additional bonus, the loop will block on waitpid while children are running, so you don't need a busy loop while you wait.



但对我来说它不会阻塞。怎么了?

最佳答案

您正在通过 WNOHANG标志,使调用非阻塞。删除此标志和 waitpid将在 0% CPU 等待,直到 child 退出。

如果采用这种方法,则可以简化代码。在子进程完成之前不需要循环,因为阻塞 waitpid电话将为您做到这一点:

for (my $i = 0; $i < $n; ++$i) {
if ($children_pids[$i] > 0) {
waitpid($children_pids[$i], 0);
print "child done\n";
$children_pids[$i] = 0;
}
}

或者,更改 sleep调用等待一秒钟。然后你的程序将每秒检查完成的 child ,而不会增加 CPU 使用率。

关于perl - 如何让waitpid阻塞循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16980450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com