2

我面临一个奇怪的问题。分叉的进程不会增加超过 64 个。

sub create_process()
{
    my $child_pid;
    my @nsitr;

    my $i = 0;

    foreach my $domain (@domains)
    {
        @nsitr = @nameservers;
        open my $dnsfh, '>', $outputfile or die "Unable to open $outputfile - $!";
        foreach my $ns (@nameservers)
        {
            print "Forking child $i\n";
            defined($child_pid = fork() ) or (die "Unable to fork a new process" && next);
            $i++;
            if($child_pid == 0)
            {
                &resolve_dns($dnsfh, $domain, $ns);
                exit;
            }

        }
        close $dnsfh;
    }
}

输出

...
...
Forking child 60
Forking child 61
Forking child 62
Forking child 63
Forking child 64
Forking child 64
Forking child 64
Forking child 64
Forking child 64
...
...
4

3 回答 3

5

Perl 没有定义这样的限制,但大多数操作系统都有。用于waitpid收割子代,或者在类 Unix 系统上,您可以使用sigaction(从POSIX模块中)忽略标志以使系统自动收割子代SIGCHLDSA_NOCLDWAIT(Linux 恰好允许您省略SA_NOCLDWAIT,但无论如何您都应该使用它。)

于 2012-04-11T18:31:12.990 回答
2

如果您想进行并行查找,您可以使用随附的演示脚本Net::DNS或查看AnyEvent::DNS

后者提供

该模块提供了许多 DNS 便利功能以及完全异步和高性能的纯 perl 存根解析器。

我没用过,但IO::Lambda::DNS也允许进行并行查询:

# parallel async queries
   lambda {
      for my $site ( map { "www.$_.com" } qw(google yahoo perl)) { 
         context $site, 'MX', timeout => 0.25; 
         dns { print shift-> string if ref($_[0]) }
      }
   }-> wait;

使用这些模块可能比手动管理分叉更好。


根据您的评论,我认为您可能误解了我想说的话。也许这会有所帮助:

#!/usr/bin/env perl

use strict; use warnings;

use AnyEvent::DNS;
use AnyEvent::Socket;
use YAML;

my %nameservers = (
    'Google' => '8.8.4.4',
    'Dnsadvantage' => '156.154.71.1',
    'OpenDNS' => '208.67.222.222',
    'Norton' => '198.153.194.1',
    'Verizon' => '4.2.2.4',
    'ScrubIt' => '207.225.209.66',
);

for my $ip ( values %nameservers ) {
    $ip = AnyEvent::DNS->new(
        server => [ parse_address($_) ],
        timeout => [3],
    );
}

my @domains = qw(example.com cnn.com bing.com);

my $cv = AnyEvent->condvar;
for my $domain (@domains) {
    for my $ns (keys %nameservers) {
        $cv->begin;
        $nameservers{$ns}->resolve(
            $domain, 'a', sub {
                $cv->end;
                print Dump { $ns => [ @{$_[0]}[0,4] ] };
            }
        );
    }
}

$cv->recv;

输出:

---
擦洗:
  -example.com
  - 192.0.43.10
---
擦洗:
  -cnn.com
  - 157.166.226.26
---
诺顿:
  -example.com
  - 192.0.43.10
---
开放DNS:
  -example.com
  - 192.0.43.10
---
优势:
  -example.com
  - 192.0.43.10
---
威瑞森:
  -example.com
  - 192.0.43.10
---
谷歌:
  -example.com
  - 192.0.43.10
---
擦洗:
  - 必应网
  - 65.52.107.149
---
诺顿:
  -cnn.com
  - 157.166.255.18
---
开放DNS:
  -cnn.com
  - 157.166.255.19
---
优势:
  -cnn.com
  - 157.166.226.25
---
威瑞森:
  -cnn.com
  - 157.166.226.26
---
谷歌:
  -cnn.com
  - 157.166.255.18
---
诺顿:
  - 必应网
  - 65.52.107.149
---
开放DNS:
  - 必应网
  - 65.52.107.149
---
优势:
  - 必应网
  - 65.52.107.149
---
威瑞森:
  - 必应网
  - 65.52.107.149
---
谷歌:
  - 必应网
  - 65.52.107.149
于 2012-04-11T18:35:01.210 回答
0

如果您在某种 Unix 系统上,您可能想要use threads模块而不是分叉。实际上它在某些方面甚至更重,可能需要一些额外的内务处理,但这可能会让你超过分叉的进程限制。不过,可能还有其他限制会阻止您创建大量线程。

于 2012-04-12T22:29:10.680 回答