无法在perl中重用线程

时间:2015-06-21 00:08:13

标签: multithreading perl queue

我正在拖尾文件,读取每一行并将其提供给线程队列,使用下面的代码

use threads;
use threads::shared;

use Thread::Queue;

use threads 'exit' => 'threads_only';

$thread_limit = 10;

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

my @thr = map {
    threads->create(
        sub {
            while ( defined( my $item = dequeue( $q ) ) ) {
                test( $item );
            }
        } );
} 1 .. $thread_limit;

my $file = File::Tail->new( "/path/File.txt" );

while ( defined( my $line = $file->read ) ) {

    my @j;
    if ( $line !~ /\s/ ) {
        push( @j, $line );
    }
    else {
        my @temp = split( /\s/, $line );
        my $size = @temp;
        for ( my $i = 0 ; $i <= $size ; $i++ ) {
            push( @j, $temp[$i] );
        }
    }

    {
        lock( $q );
        $q->enqueue( @job );
    }
}

问题:

thread_limit = 10

现在,一旦达到“活动线程数”= 1,线程就会停止,尽管队列中有更多工作项要出列。你能帮忙吗? 读取工作项的文件将是连续的。

1 个答案:

答案 0 :(得分:0)

程序中的每个线程都以Undefined subroutine &main::dequeue消失,主程序以Can't locate object method "new" via package "File::Tail"消亡。

  • 添加use File::Tail;
  • dequeue( $q )更改为$q->dequeue()

添加use strict; use warnings;(您总是使用它)会发现问题。

  • $q->enqueue( @job );更改为$q->enqueue( @j );。 (始终使用use strict; use warnings;!)

当您解决上述问题时,会发现更多问题。

  • 删除lock( $q );。 1)它不起作用,因为它不是共享变量,2)只锁定一个地方是没用的,3)Thread :: Queue是线程安全的。
  • 子程序test不存在。

应用这些修补程序和其他一些清理后,您将获得以下内容:

use strict;
use warnings;
use threads;
use File::Tail         qw( );
use Thread::Queue 3.01 qw( );

use constant NUM_WORKERS      => 10;
use constant COMMAND_FILE_QFN => '...';
use constant DEBUG            => 1;

sub worker {
    my ( $item ) = @_;
    print( "Processed $item.\n" );
}

my $q = Thread::Queue->new();
for (1..NUM_WORKERS) {
    async {
        while ( defined( my $item = $q->dequeue() ) ) {
            worker( $item );
        }
    };
}

my $tail = File::Tail->new(
    name        => COMMAND_FILE_QFN,
    maxinterval => DEBUG ? 1 : 60,
);
while ( defined( my $line = $tail->read() ) ) {
    $q->enqueue( split( ' ', $line ) );
}

$q->end();
$_->join() for threads->list();