我在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;
答案 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