2013-01-10 20 views
0

我有简单的多线程站点检查器。 我试图在环txt文件打开这个目录用线程打开的perl队列文件

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(); 
    } 
} 

但它仅适用于第一个文件和程序终止工作。 任何人都可以帮忙吗? 谢谢。

+1

您是否使用严格;使用警告'? '@ threads'声明在哪里?为什么它不在外部循环中声明*?另外,我看不到线程和'@ sites'之间的任何交互。你知道['Thread :: Queue'](https://metacpan.org/module/Thread::Queue)吗? – amon

+0

是的。因为这与问题无关。子程序检查使用@sites。 – Wolfgang

+4

如果你不知道为什么你的程序不能正常工作,那么你不能说与问题相关的是什么。请发布您的完整代码。我在这个片段中根本看不到任何声明,我怀疑在其他地方对'@ sites','$ threads'或'@ threads'的处理不当。 – Borodin

回答

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; 
+0

很好,谢谢! – Wolfgang

2

“Site checker”肯定是一个I/O绑定问题,而线程/分支更适合解决CPU绑定问题。如果使用异步方法,网络上的并行请求可以是单进程的。下面是使用YADA模块从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;