Multithreading 用线程打开perl队列文件

Multithreading 用线程打开perl队列文件,multithreading,perl,Multithreading,Perl,我有一个简单的多线程站点检查器。 我正在尝试在这个目录中打开循环中的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);#chec

我有一个简单的多线程站点检查器。 我正在尝试在这个目录中打开循环中的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();
   }
}
但它只适用于第一个文件和终止的程序。 有人能帮忙吗? 谢谢。

“站点检查器”当然是一个I/O限制的问题,而线程/分叉更适合解决CPU限制的问题。若使用异步方法,则网络上的并行请求可以是单个进程。下面是一个非常简单的检查器,它使用CPAN中的模块,默认情况下使用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;
“站点检查器”当然是一个I/O限制的问题,而线程/分叉更适合解决CPU限制的问题。若使用异步方法,则网络上的并行请求可以是单个进程。下面是一个非常简单的检查器,它使用CPAN中的模块,默认情况下使用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;

如果使用Perl执行线程,则需要避免以下几件事:

  • 过度分叉/创建新流程
  • 共享状态,或者共享任何不是不变或同步的东西
您的代码使用了
$threads
的硬连线限制。但是您将其传递并索引到一个全局(*shubdder*)数组(忘记了第一个索引),因此某些站点可能会被取消选中。此外,您还为每一组站点创建了一组新的线程,这似乎是浪费

现在让我们假设我们有一个线程::队列。然后,我们首先创建几个线程:

#!/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
}
文件完成后,我们将
unde
值排队;这会导致线程终止:

$queue->enqueue( (undef) x THREADS );
$_->join for @threads;

如果使用Perl执行线程,则需要避免以下几件事:

  • 过度分叉/创建新流程
  • 共享状态,或者共享任何不是不变或同步的东西
您的代码使用了
$threads
的硬连线限制。但是您将其传递并索引到一个全局(*shubdder*)数组(忘记了第一个索引),因此某些站点可能会被取消选中。此外,您还为每一组站点创建了一组新的线程,这似乎是浪费

现在让我们假设我们有一个线程::队列。然后,我们首先创建几个线程:

#!/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
}
文件完成后,我们将
unde
值排队;这会导致线程终止:

$queue->enqueue( (undef) x THREADS );
$_->join for @threads;

您是否使用了严格的
;使用警告
@threads
在哪里声明?为什么不在外循环中声明?另外,我看不到线程和
@站点之间的任何交互。你知道吗?知道。因为这与问题无关。子程序检查使用@sites。如果您不知道程序为什么不工作,则无法说明与问题相关的内容。请张贴您的全部代码。我在这个片段中根本看不到任何声明,我怀疑
@sites
$threads
@threads
其他地方处理不当;使用警告
@threads
在哪里声明?为什么不在外循环中声明?另外,我看不到线程和
@站点之间的任何交互。你知道吗?知道。因为这与问题无关。子程序检查使用@sites。如果您不知道程序为什么不工作,则无法说明与问题相关的内容。请张贴您的全部代码。我在这个片段中根本看不到任何声明,我怀疑
@sites
$threads
@threads
其他地方处理不当。