Perl Monks ( http://www.perlmonks.org/?node_id=735923 ) での最初の回答をスレッド化されたモデルに拡張しようとしましたが、役に立ちませんでした。coderef を渡すことができないという問題が発生し続けます
私のスーパークラスでは、スレッドプールをパッケージ変数として定義して、サブクラス間で共有できるようにします。
package Things::Generic;
my $Qwork = new Thread::Queue;
my $Qresults = new Thread::Queue;
my @pool = map { threads->create(\&worker, $Qwork, $Qresults) } 1..$MAX_THREADS;
sub worker {
my $tid = threads->tid;
my( $Qwork, $Qresults ) = @_;
while( my $work = $Qwork->dequeue ) {
my $result = $work->process_thing();
$Qresults->enqueue( $result );
}
$Qresults->enqueue( undef ); ## Signal this thread is finished
}
sub enqueue {
my $self = shift;
$Qwork->enqueue($self);
}
sub new {
#Blessing and stuff
}
.
.
次にサブクラスです。process_thing() メソッドがあることが保証されています。
package Things::SpecificN;
use base qw (Things::Generic);
sub new() {
#instantiate
}
sub do_things {
my $self = shift;
#enqueue self into the shared worker pool so that "process_thing" is called
$self->enqueue();
}
sub process_thing() {
#Do some work here
return RESULT;
}
#
Main
my @things;
push @things, Things::Specific1->new();
push @things, Things::Specific2->new();
.
.
push @things, Things::SpecificN->new();
#Asynchronously kick off "work"
foreach my $thing (@things) {
$thing->do_things();
}
私の目標は、「作業」のリストをキューに入れることです。各スレッドはキューから作業を取得し、それが何であっても実行します。各 Thing には独自の作業がありますが、その作業を行う関数は「process_thing」と呼ばれることが保証されます。スレッドプールがキューからエントリを取得して「何か」を実行するようにしたいだけです。Android AsyncTask に似た機能について説明していると思います。
私の Perl は Thread::Queue::Any に対して十分に高くありません