检查活动线程的数量

时间:2014-09-09 17:49:06

标签: multithreading perl

我在Perl中实现了一个boss-worker crew线程模型。 由于例外,工作线程异常退出。

一旦所有工作线程死亡(异常退出),作业就会停滞不前,因为没有线程可以处理workers_fn并且boss线程一直在接受作业。

Thread 2 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 3 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 4 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 5 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 6 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 7 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 8 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 9 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 10 terminated abnormally: Illegal division by zero at threading.pl line 20.
Thread 11 terminated abnormally: Illegal division by zero at threading.pl line 20.

在任何时候,我如何准确地检测到活着的工人数量?

#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use diagnostics;

use threads;
use Thread::Queue;

use Data::Dumper;

use constant {
    WORKERS_CNT => 10,    
};

my $queue= new Thread::Queue();
sub workers_fn{

    #Producing exceptions DELIBERATELY as a test case 
    my $random_number = int(time);
    if($random_number %2==0 || $random_number %3==0 || $random_number %5==0){
        print "CRASHED:".5/($random_number %2);
        print "\n";
    }

    while (my $query = $queue->dequeue) {
        print "DEQ(".threads->tid.") :$query\n";
    }

}
sub master_fn(){
    my $TotalEntry=10000;
    while($TotalEntry -- > 0){
        my $query = localtime;
        $queue->enqueue($query);
        print "ENQ(".threads->tid.") :$query\n";
        sleep(1);

        #check which worker threads are alive
        {
          #HOW TO CHECK NUMBER OF ALIVE THREADS?????????????
        }

    }
}

my $master_th=threads->create(\&master_fn);
my  @worker_th=map threads->create(\&workers_fn), 1..WORKERS_CNT;
$master_th->join;
$queue->enqueue(undef) for 1..WORKERS_CNT;

for (@worker_th){
    $_->join;

1 个答案:

答案 0 :(得分:4)

my $running = threads->list(threads::running);

$ perl -Mthreads -Mthreads::shared -MTime::HiRes=sleep -E'
   my $hold : shared;
   {
      lock($hold);

      async { sleep 1; die "ack" };
      async { lock($hold) };

      while (1) {
         my $running = threads->list(threads::running);
         say $running;
         last if $running < 2;
         sleep 0.1;
      }
   }

   $_->join for threads->list;
'
2
2
2
2
2
2
2
2
2
2
Thread 1 terminated abnormally: ack at -e line 6.
1