2009-09-26 5 views
7

Perlでマルチスレッドを実行するためにどのモジュールを調べるべきですか?Perlでマルチスレッドを実行するためにどのようなモジュールを検討する必要がありますか?

私はかなり低いパフォーマンスを狙っています。私はスレッドが同時に複数のワーカーを実行し、それぞれがさまざまな時間の間スリープ状態になるようにしたいと考えています。

答えて

7

最近のPerlのバージョンでは、スレッドをサポートしています。 perl -V:usethreadsを実行して、システムで利用可能かどうかを確認してください。

$ perl -V:usethreads 
usethreads='define' 

perldoc threadsは、それらを使用するためのかなり良い紹介します。

+2

ithreadsは何でも使用しないでください。 – jrockway

+0

リンクは機能していません –

7

パフォーマンスに大きな問題がない場合は、fork複数のプロセスを処理する方が、スレッドを処理するよりも簡単です。私は頻繁にParallel::ForkManagerを使用していますが、それは非常に簡単ですが、それは何か非常に良いです。

5

プリエンプティブマルチスレッドを必要としないようです。その場合は、POEの協力モデルを見てください。あなたのコードは、あなたが決めるときに他のスレッドにしか得られないので、一度に1つのスレッドしか実行されないので、開発とデバッグがずっと簡単になります。

+3

POEはマルチスレッドやマルチプロセッシングを暗黙的にサポートしていませんが、 'POE :: Wheel :: Run'はフォークされたプロセスでコードを実行し、I/Oと終了ステータスPOEイベントに変換する。ブロッキングコードを囲むことは非常に便利です。 – hobbs

+0

私は2番目に_ – xxxxxxx

2

Coroは、協調的なマルチタスクのための素敵なモジュールです。

時間の99%、これはPerlでスレッドをしたい場合に必要なものです。

複数のコアが使用可能なときにスレッドのコードを高速化したい場合は、間違ったパスを使用します。 Perlは他の言語より50倍遅いです。 2つのCPU上で実行するようにコードを書き直すことは、1つのCPU上で他の言語より25倍遅く実行されることを意味します。遅い部分を別の言語に移植する努力をするのがよいでしょう。

しかし、IOに他の "スレッド"をブロックしたくない場合、Coroはまさにあなたが望むものです。

+1

開発スピードもあります。 –

+0

私はこの議論に疲れています:)私はハスケルでPerlのように素早く一緒にハックできる多くのことがあり、ハスケルはperlよりはるかに高速に動作します。 – jrockway

+0

私はこれに同意しますが、Perlは他の言語よりも50倍遅いと主張するのは、特定の操作にのみ適用される誇張です。ご存じのように、PerlのIOと正規表現は最適なコンパイル言語と同等です。プログラマーがボトルネックを特定でき、開発者の時間があれば、Inline :: Cを使ってDSLにコードを書く価値があるかもしれません。優れたパフォーマンスのスピードアップを得るためにDSLでコードの大部分を書き直さなければならない場合、Perlを完全に削除することは理にかなっているかもしれません。 –

9

マルチスレッドにしたくない理由はたくさんあります。ただし、マルチスレッドにしたい場合は、次のコードを参考にしてください。いくつかのジョブを作成し、それらをスレッドセーフ待ち行列に入れ、キューからジョブを引き出して完了させるいくつかのスレッドを開始します。各スレッドは、それ以上ジョブが見えなくなるまでループ内のキューからジョブを引き出します。プログラムはすべてのスレッドが終了するのを待ってから、ジョブに費やした合計時間を出力します。

#!/usr/bin/perl 

use threads; 
use Thread::Queue; 
use Modern::Perl; 

my $queue= Thread::Queue->new; 
my $thread_count= 4; 
my $job_count= 10; 
my $start_time= time; 
my $max_job_time= 10; 

# Come up with some jobs and put them in a thread-safe queue. Each job 
# is a string with an id and a number of seconds to sleep. Jobs consist 
# of sleeping for the specified number of seconds. 
my @jobs= map {"$_," . (int(rand $max_job_time) + 1)} (1 .. $job_count); 
$queue->enqueue(@jobs); 

# List the jobs 
say "Jobs IDs: ", join(", ", map {(split /,/, $_)[0]} @jobs); 

# Start the threads 
my @threads= map {threads->create(sub {function($_)})} (1 .. $thread_count); 

# Wait for all the threads to complete their work 
$_->join for (@threads); 

# We're all done 
say "All done! Total time: ", time - $start_time; 

# Here's what each thread does. Each thread starts, then fetches jobs 
# from the job queue until there are no more jobs in the queue. Then, 
# the thread exists. 
sub function { 
    my $thread_id= shift; 
    my ($job, $job_id, $seconds); 
    while($job= $queue->dequeue_nb) { 
    ($job_id, $seconds)= split /,/, $job; 
    say "Thread $thread_id starting on job $job_id ", 
     "(job will take $seconds seconds)."; 
    sleep $seconds; 
    say "Thread $thread_id done with job $job_id."; 
    } 
    say "No more jobs for thread $thread_id; thread exiting."; 
} 
関連する問題