控制在perl中给定时间同时运行的线程的最大数量

时间:2013-02-22 06:08:50

标签: multithreading perl worker

我有一个包含文件@arr=(a.txt,b.txt,c.txt);

列表的数组

我正在迭代数组并使用foreach循环处理文件;该文件的每一行都将生成一个sql,并将在数据库服务器上运行。

我想用文件的每一行创建一个线程并查询数据库。我还想同时控制线程的最大数量。

3 个答案:

答案 0 :(得分:1)

您可以使用基于Thread::Pool的系统。或任何基于Boss/Worker模型的系统。

答案 1 :(得分:1)

这只是一个简单的工人模型,一个理想的场景。没问题。

use threads;
use Thread::Queue qw( );

use constant NUM_WORKERS => 5;

sub work {
   my ($dbh, $job) = @_;
   ...
}

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

   my @threads;
   for (1..NUM_WORKERS) {
      push @threads, async {
         my $dbh = ...;
         while (my $job = $q->dequeue()) 
            work($dbh, $job);
         }
      };
   }

   while (<>) {
      chomp;
      $q->enqueue($_);
   }

   $q->enqueue(undef) for 1..@threads;
   $_->join() for @threads;
}

将文件名作为参数传递给脚本,或者将它们分配给脚本中的@ARGV

local @ARGV = qw( a.txt b.txt c.txt );

答案 2 :(得分:0)

有趣的是我手动控制要运行的线程数。我使用线程id的哈希 [代码片段]     我的%thr; #my哈希的线程

$count=1;
$maxthreads=5;

while (shift (@data) {
  $syncthr = threads->create(sub {callfunction here}, {pass variables});
  $tid = $syncthr->tid; #get the thread ID
  $thr{$tid} = $syncthr;
  if ($count >= $maxthreads) {
    threads->yield();
    while (1) { # loop until threads are completed
    $num_run_threads = keys (%thr);
    foreach $one_thread ( keys %thr ) {
       if ($thr{$one_thread}->is_running() ) { # if thread running check for error state
          if ($err = $thr{$one_thread}->error() } {
             [ do stuff here]
          }
          # otherwise move on to next thread check
       } else { # thread is either completed or has error
          if ($err = $thr{$one_thread}->error()) {
            [ check for error again cann't hurt to double check ]
          }
          if ($err = $thr{$one_thread}->join()) {
             print "Thread completed id: [$one_thread]\n";
          }
          delete $thr{$one_thread}; # delete the hash since the thread is no more
          $num_run_threads = $num_run_threads - 1; # reduce the number of running     threads
       }
    } # close foreach loop
    @threads = threads->list(threads::running); # get threads
    if ($num_run_threads < $maxthreads ) {
      $count = $num_run_threads; # reset the counter to number of threads running
      if ( $#data != -1 ) { # check to make sure we still have data
        last; # exit the infinite while loop
      } else {
        if (@threads) {
          next; # we still have threads continue with processing
        } else {
          { no more threads to process exit program or do something else }
        }
      } # end else
    } # end threads running
    } # end the while statement
    #Check the threads to see if they are joinable
    undef @threads;
    @threads = threads->joinable()
    if (@threads) {
      foreach $mthread(@threads) {
        if ($mthreads != 0) {
          $thr->join();
        }
      } #end foreach
    } #end @threads
  } #end the if statement
  $count++; Increment the counter to get to number of max threads to spawn
}

这绝不是一个完整的计划。而且,我把它改成了非常乏味。但是,我已经成功使用了一段时间。特别是在OO Perl中。这对我有用,并且有很多用途。我可能错过了一些错误检查,尤其是超时,但我在线程本身。顺便说一下,线程实际上是我调用的子例程。