目次

#contents

内容

参考

スクリプト例

単純なスレッド化

use strict;
use warnings;
use Data::Dumper;
use utf8;

use threads;
use threads::shared;

use Encode;
use Config;

### スレッドが有効化を調べる
$Config{useithreads} || die "not ithread compiled\n";

### 変数の共有
my $data : shared = 0;
our $THREAD_COUNT : shared = 0;

### 出力バッファを無効化
$| = 1;

for ( 1 .. 10 ){
    my $thread = threads->new( \&sub1, $data );
    $thread->join();
}

sub sub1{
    binmode( STDOUT, ":encoding(utf8)" );
    my $foo = shift;
    $data = $foo + 1;
    print "in the thread $data あああ\n";
    sleep 1;
    return;
}
  • グローバルな位置でbinmodeを使って出力のエンコードを指定するとsegmentation faultが発生する
  • threads::sharedで共有した変数に頻繁にアクセスすると処理速度が遅くなる
    • スカラー変数が一つだけなら影響は小さいが、配列・連想配列はインパクトが大きい。
    • 参照しているだけでも遅い。ロックの有無は関係なし。
    • スレッド化で処理速度が改善されない場合は、スレッドのスコープ内で変数を保持し、そこに値がない場合だけ共有変数にアクセスするようチューニングする。

Semaphoreを使って同時実行スレッド数を制限

#!/usr/bin/perl

use strict;
use threads;
use Thread::Semaphore;
use threads::shared;
use constant {
    THREAD_COUNT=>10,
    THREAD_LIMIT=>5,
};
 
our $LOOPC : shared = 0;
our $THREAD_COUNT : shared = 0;
$| = 1;
our $SEMA = new Thread::Semaphore(THREAD_LIMIT);
 
my %th;

for my $id(1 .. THREAD_COUNT) {
    $th{$id} = new threads(\&run,$id,100,$SEMA);
    
}

for (1 .. THREAD_COUNT) {
    $th{$_}->join();
}

sub run {
    my($threadid,$randarg,$sema) = @_;
    $randarg ||= 10;
 
    $sema->down();
    {
        lock $THREAD_COUNT;
        $THREAD_COUNT++;
    }
    for (1 .. 5) {
    {lock $LOOPC; $LOOPC++;}
        printf("ID%2d Rand%2d LOOP%2d ; $THREAD_COUNT threads_running:\n",$threadid,int rand($randarg),$LOOPC);
        threads::yield();
    }
    {
        lock $THREAD_COUNT;
        $THREAD_COUNT--;
    }
    $sema->up();
}
  • 全てのスレッド生成が完了してからjoinをする(=roopを2回実行)
    • でないと、スレッドが同時に起動しない
  • もし「Scalars leaked]が出たら、new Thread::Semaphoreを、共有変数の前に移動する
    • 実際に使用するスクリプトでエラーがでたが、このサンプルでは再現しない・・・。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-09-25 (日) 19:27:03 (446d)