无法在 perl 中重用线程 [英] Not able to re-use threads in perl

查看:61
本文介绍了无法在 perl 中重用线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am tailing a file, reading each line and feeding it to thread queue, using the below code

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

问题:

线程限制 = 10

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

now, once it reaches "number of active threads" = 1, threads stop, though the queue has more work items to dequeue. Can you please help? Reading file for work items will be continuous.

推荐答案

你程序中的每个线程都以 未定义的子程序 &main::dequeue 结束,主程序以 结束无法定位对象方法new";通过包File::Tail".

Each of the threads in your program dies with Undefined subroutine &main::dequeue and the main program dies with Can't locate object method "new" via package "File::Tail".

  • 添加use File::Tail;.
  • dequeue( $q ) 改为 $q->dequeue().
  • Add use File::Tail;.
  • Change dequeue( $q ) to $q->dequeue().

添加use strict;使用警告;(你应该总是使用)发现问题.

Adding use strict; use warnings; (which you should always use) finds problems.

  • $q->enqueue(@job); 改为 $q->enqueue(@j);.

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

Still more problems are revealed as you fix the above.

  • 移除lock( $q );.1) 它不会工作,因为它不是共享变量,2) 只锁定一个地方是没有用的,以及 3) Thread::Queue 是线程安全的.
  • 子程序 test 不存在.
  • Remove lock( $q );. 1) It's won't work since it's not a shared variable, 2) Locking in only one place is useless, and 3) Thread::Queue is thread-safe.
  • Subroutine test doesn't exist.

应用这些修复和其他一些清理后,您会得到以下内容:

After applying those fixes and some other cleanup, you get the following:

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 ( $job ) = @_;
    print( "Processed $job.\n" );
}

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

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

这篇关于无法在 perl 中重用线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆