无法在 perl 中重用线程 [英] Not able to re-use threads in 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屋!