加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – 如何使waitpid阻止循环

发布时间:2020-12-16 06:23:11 所属栏目:大数据 来源:网络整理
导读:以下代码运行2个孩子,他们将等待10秒并终止.父母坐在一个循环中,等待孩子们终止: #!/usr/bin/perluse strict;use warnings;use POSIX ":sys_wait_h";sub func# {{{{ my $i = shift; print "$i startedn"; $| = 1; sleep(10); print "$i finishedn";}# }}}
以下代码运行2个孩子,他们将等待10秒并终止.父母坐在一个循环中,等待孩子们终止:

#!/usr/bin/perl

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

sub func
# {{{
{
      my $i = shift;
      print "$i startedn";
      $| = 1;
      sleep(10);
      print "$i finishedn";
}
# }}}

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 donen";
                        $children_pids[$i] = 0;
                  } else {
                        # Still waiting on this child
                        #print "waitingn";
                        $stillWaiting = 1;
                  }
            }
            #Give up timeslice and prevent hard loop: this may not work on all flavors of Unix
            sleep(0);
      }
} while ($stillWaiting);

print "parent finishedn";

代码基于这个答案:Multiple fork() Concurrency

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

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,直到孩子退出.

如果采用这种方法,则可以简化代码.在子项完成之前无需循环,因为阻塞waitpid调用将为您执行此操作:

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

或者,将睡眠呼叫更改为等待一秒钟.然后,您的程序将每秒检查已完成的子项,而不会提高CPU使用率.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读