0

マルチスレッドを備えたシンプルなサイトチェッカーがあります。このディレクトリでループtxtファイルを開こうとしています

my @files = glob( '*.txt' );

foreach my $file(@files){

   @sites=load_file($file);
   $total_count = scalar(@sites);

   for my $t (1..$threads) {
     push @threads, threads->create(\&check, $t);#check- main subroutine
     threads->create(\&stat)->join() if $t == $threads;#stat - realtime statistics(good/bads) sites
   }

   foreach my $t (@threads) {
     $t->join();
   }
}

ただし、最初のファイルとプログラムが終了した場合にのみ機能します。誰でも助けることができますか?ありがとう。

4

2 に答える 2

2

「サイトチェッカー」は確かにI/Oバウンドの問題ですが、スレッド/フォークはCPUバウンドの問題を解決するのに適しています。非同期アプローチを使用する場合、ネットワークを介した並列要求は単一プロセスになる可能性があります。これは、CPANのYADAモジュールを使用する非常に単純なチェッカーの1つで、デフォルトで4つの並列接続を使用します。

#!/usr/bin/env perl
use common::sense;

use YADA;

YADA->new->append(
    [qw[
        http://www.cpan.org/modules/by-category/02_Language_Extensions/
        http://www.cpan.org/modules/by-category/02_Perl_Core_Modules/
        http://www.cpan.org/modules/by-category/03_Development_Support/
        http://www.cpan.org/modules/by-category/27_Pragma/
        http://www.cpan.org/modules/by-category/28_Perl6/
        http://www.cpan.org/modules/by-category/99_Not_In_Modulelist/
    ]] => sub {
        say $_[0]->final_url;
        say ${$_[0]->header};
    },
)->wait;
于 2013-01-10T15:58:08.440 に答える
2

Perlでスレッド化を行っている場合、避けるべきことがいくつかあります。

  • 過度の分岐/新しいプロセスの作成
  • 共有状態、または不変または同期されていないものを共有します!

コードでは、ハードワイヤード制限のを使用しています$threads。ただし、グローバル(* shudder *)配列に渡してインデックスを作成する(最初のインデックスを忘れる)ため、一部のサイトがチェックされていない可能性があります。また、サイトのセットごとに新しいスレッドのセットを作成しますが、これは無駄に思えます。

ここで、Thread::Queueがあると仮定します。次に、いくつかのスレッドを作成することから始めます。

#!/usr/bin/perl

use strict; use warnings; use threads; use Thread::Queue;
use constant THREADS => 5; # or whatever

my $queue = Thread::Queue->new();

my @threads = map threads->new(\&check, $queue),  1 .. THREADS;

私たちのcheckサブルーチンは引数としてキューを取り、そこからサイトを取得します。

sub check {
  my $q = shift;
  while (defined(my $site = $q->dequeue)) {
    ...; # check the site.
  }
}

次に(スレッドを開始した後)、キューをサイトで埋めます。

for my $file (@files) {
   my @sites = load_file($file);
   $queue->enqueue( @sites ); # keep queue operations to minimum
   # maybe wait until there are less that n sites in the queue
}

ファイルが終了したら、undef値をキューに入れます。これにより、スレッドが終了します。

$queue->enqueue( (undef) x THREADS );
$_->join for @threads;
于 2013-01-10T16:37:43.780 に答える