- 论坛徽章:
- 0
|
我把这个程序放在linux系统上运行的时候是正常的,因为linux能fork更多子进程,所以修改了下一些数值和输出,代码如下:- #!/usr/bin/env perl
- use strict;
- use warnings;
- use POSIX ":sys_wait_h"; # for nonblocking read
- my %children;
- my $count = 0;
- my $max = shift @ARGV || 100000;
- my $num = 0;
- while ($num++ < $max) {
- my $pid = fork();
- until (defined $pid) {
- print "Failed to fork new subprocess, num is $num, try to reap zombies now.\n";
- die "Can't fork. count is $count\n" if $count == 0;
- unless (_reap_subprocess(\%children, \$count)) {
- die "Can't fork subprocess even when no " .
- "subprocess is running.\n";
- }
- print "Zombies reaped, try to fork again.\n";
- $pid = fork();
- }
- $children{$pid} = 1;
-
- if ($pid == 0) {
- sleep 5;
- exit 0;
- }
- $count++;
- #print("pid is $pid, num is $num\n");
- #_reap_subprocess(\%children, \$count) if $count > 63; # 62 works here
- }
- _reap_subprocess(\%children, \$count) while ($count);
- sub _reap_subprocess {
- my ($child_ref, $count_ref) = @_;
- return 0 unless $count_ref;
- my %child = %$child_ref;
-
- my $reaped;
- while (1) {
- # last if reaped one valid subprocess
- my $pid = waitpid(-1, WNOHANG);
- if ($pid == -1 or $pid == 0) {
- last if $reaped;
- print "No HANG, wait 5, count is $count_ref, pid is $pid.\n";
- sleep 5;
- }
- elsif (defined $child{$pid}) {
- # print "pid is $pid, count is $count_ref\n";
- delete $child_ref->{$pid};
- $count_ref--;
- $reaped = 1;
- }
- }
-
- return 1;
- }
复制代码 代码输出如下:
Failed to fork new subprocess, num is 31822, try to reap zombies.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 54765, try to reap zombies.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 54765, try to reap zombies.
No HANG, wait 5, count is 12656, pid is 0.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 67421, try to reap zombies.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 67421, try to reap zombies.
No HANG, wait 5, count is 12656, pid is 0.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 80081, try to reap zombies.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 80081, try to reap zombies.
No HANG, wait 5, count is 12656, pid is 0.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 92737, try to reap zombies.
Zombies reaped, try to fork again.
Failed to fork new subprocess, num is 92737, try to reap zombies.
No HANG, wait 5, count is 12656, pid is 0.
Zombies reaped, try to fork again.
No HANG, wait 5, count is 7264, pid is 0.
No HANG, wait 5, count is 788, pid is 0.
整个代码正常结束。
因此,我觉得可能是win7系统中perl自己仿真的fork和waitpid与linux系统调用的有所差别,才导致在fork失败后waitpid(-1, WNOHANG)不能正常收割子进程。 |
|