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答案说:
但对我来说它并没有阻止.怎么了? 解决方法
你正在传递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使用率. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |