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して無視SIGCHLDし、システムに自動的に子をリープさせることができます。SA_NOCLDWAIT(Linux ではたまたま を省略できますSA_NOCLDWAITが、とにかく使用する必要があります。)

于 2012-04-11T18:31:12.990 に答える
2

並列ルックアップを実行したい場合は、付属のデモ スクリプトを使用するか、 AnyEvent::DNSNet::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
---
OpenDNS:
  -example.com
  - 192.0.43.10
---
利点:
  -example.com
  - 192.0.43.10
---
ベライゾン:
  -example.com
  - 192.0.43.10
---
グーグル:
  -example.com
  - 192.0.43.10
---
スクラブ:
  -bing.com
  - 65.52.107.149
---
ノートン:
  - cnn.com
  - 157.166.255.18
---
OpenDNS:
  - cnn.com
  - 157.166.255.19
---
利点:
  - cnn.com
  - 157.166.226.25
---
ベライゾン:
  - cnn.com
  - 157.166.226.26
---
グーグル:
  - cnn.com
  - 157.166.255.18
---
ノートン:
  -bing.com
  - 65.52.107.149
---
OpenDNS:
  -bing.com
  - 65.52.107.149
---
利点:
  -bing.com
  - 65.52.107.149
---
ベライゾン:
  -bing.com
  - 65.52.107.149
---
グーグル:
  -bing.com
  - 65.52.107.149
于 2012-04-11T18:35:01.210 に答える
0

ある種の Unix システムを使用している場合はuse threads、フォークの代わりにモジュール化することをお勧めします。実際にはいくつかの面でさらに重く、追加のハウスキーピングが必要になる場合がありますが、これにより fork プロセスの制限を超えることができます。ただし、大量のスレッドを作成することを妨げる他の制限がある可能性があります。

于 2012-04-12T22:29:10.680 に答える