我在这里一次提供了一些指导,包括以下代码段:
my $q = Thread::Queue->new();
sub worker {
my ($job, $action) = @_;
Build($job, $action);
}
for (1..NUM_WORKERS) {
async {
while (defined(my $job = $q->dequeue())) {
worker($job, 'clean');
}
};
}
$q->enqueue($_) for @compsCopy;
# When you're done adding to the queue.
$q->end();
$_->join() for threads->list();
重用q
的最佳选择是什么?目前,我只是制作新的q
个对象,q2
,q3
并为我想要执行的每个$action
再次执行此操作。有更好的方法吗?我可能会传递一系列"动作"我想执行,并希望尽可能避免重复此代码7次。
也许我不完全理解Thread::Queue
是什么......
答案 0 :(得分:0)
您应该为一个方向使用一个队列。如果您只想进行一些操作,请使用一个队列。如果您想报告错误并在主线程或其他线程中处理这些错误,那么您将使用两个队列。
以供简单使用,供您参考:
use strict;
use warnings;
use threads;
use threads;
use Thread::Queue;
my $q = Thread::Queue->new(); # A new empty queue
my %seen: shared;
# Worker thread
my @thrs = threads->create(\&doOperation ) for 1..5;#for 5 threads
add_file_to_q('/tmp/');
$q->enqueue('//_DONE_//') for @thrs;
$_->join() for @thrs;
sub add_file_to_q {
my $dir = shift;
my @files = `ls -1 $dir/`;chomp(@files);
#add files to queue
foreach my $f (@files){
# Send work to the thread
$q->enqueue($f);
print "Pending items: "$q->pending()."\n";
}
}
sub doOperation () {
my $ithread = threads->tid() ;
while (my $filename = $q->dequeue()) {
# Do work on $item
sleep(1) if ! defined $filename;
return 1 if $filename eq '//_DONE_//';
next if $seen{$filename};
print "[id=$ithread]\t$filename\n";
$seen{$filename} = 1;
### add files if it is a directory (check with symlinks, no file with //_DONE_// name!)
add_file_to_q($filename) if -d $filename;
}
return 1;
}