如何重用Thread :: Queue中的队列?

时间:2014-04-01 17:52:34

标签: multithreading perl queue

我在这里一次提供了一些指导,包括以下代码段:

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个对象,q2q3并为我想要执行的每个$action再次执行此操作。有更好的方法吗?我可能会传递一系列"动作"我想执行,并希望尽可能避免重复此代码7次。

也许我不完全理解Thread::Queue是什么......

1 个答案:

答案 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;
}