top

TOP  RSS  Login

Perl - threads

概要

マルチスレッド処理を行う為に用いられるモジュール。

簡単な例

作られたスレッドと並行して処理が行われることの確認。

use threads;

my $th = threads->new(sub {
    for(1..10){
        print "thread says $_\n";
        sleep(rand(3)+1);
    }
});

for(1..10){
    print "main $_\n";
        sleep(rand(3)+1);
}

$th->join;
print "end\n";

上記の例では、new() にコードリファレンスを渡して新たにスレッドを作成する。その後メインの処理とスレッドの処理とが並行して行われ、join() でスレッドの終了を待っている。

その他の例

use threads;
use threads::shared;
use feature qw(:5.10);

my @th;
my $v = 1;
my $v_shared : shared = 1;
my @a_shared : shared = ();
my %h_shared : shared = ();

for(1..10){
    push(@th, threads->new(sub {
        my $i = threads->tid;
        $v++;
        $v_shared++;
        push(@a_shared, $i);
        $h_shared{$i} = $i;
        local($SIG{INT}) = sub {
            say "${i} caught SIGINT!";
            threads->exit();
        };
        say "${i} start";
        my $n = int(rand(10)) + 1;
        say "${i} sleeping ${n}sec...";
        sleep($n);
        say "${i} waked up";
        say "${i} done";
    }));
}

sleep(2);
say "cleanup...";

for my $t (grep { $_->is_running } @th){
    threads->new(sub {
        $t->kill("INT")->detach();
        say "thread ". $t->tid ." detached";
    });
}

$_->join() for(threads->list(threads::joinable));

say "v = $v";
say "v_shared = $v_shared";
say "a_shared = (". join(", ", @a_shared).")";
say "h_shared = (". join(", ", map { qq|$_ => $h_shared{$_}| }(keys(%h_shared))). ")";
say "end";

sleep しているスレッドに kill で SIGINT を送ってもすぐには受け取ってくれず、sleep から目覚めた後に処理される。待てない場合 detach でデタッチする。

変数はその値が各スレッドにコピーされる。変数をスレッド間でコピーではなく共有する場合は、use threads::shared して、変数の宣言時に shared 属性を付ける。

リンク

Last modified:2009/08/26 16:33:35

0.075431