読者です 読者をやめる 読者になる 読者になる

スレッドでの変数共有(Threadとithreadsの違い)

Perl

Thread(Perl 5.6?)ならasyncでスレッドを実行すれば、同じモジュールのレキシカル変数(myで宣言した変数)を共有できた。

プログラミングPerl P.536の例がithreads(Perl 5.8)では実行できない

ithreadsではthreads::sharedを使って変数を明示的に共有する必要がある。

use threads::shared;

共有データと非共有データ

iスレッド と 5.005型スレッドの間の(もっといえば、そこから外れる多くのスレッドシステムにとっての)最大の違いは、デフォルトでデータが共有されないという点だ。新しいperlスレッドが生成されるとき、現在のスレッドに関連する全てのデータは新しいスレッドにコピーされる。続いてそのデータは新しいスレッド内でプライベートなものとなる!これはUNIXのプロセスがforkするときに起きることと似ている。ただしこの場合、実際のforkではメモリ上での置き換えが起こるのに対して、そのデータは同一プロセッサ内の違うメモリ部分にコピーされるだけであるという点は除く。

出典 http://perldoc.jp/docs/perl/5.8.0/perlthrtut.pod


以下の例では、両方とも最後に"2"が表示されるはず。ただしThread(Perl 5.6)は未テスト。

#
# Perl 5.6 スレッドの変数共有テスト
#
use Thread 'async';

my $common = 0;

$t1 = async {
my $tid = Thread->self->tid;
print "thread $tid\n";

$common++;
};

$t2 = async {
my $tid = Thread->self->tid;
print "thread $tid\n";

$common++;
};


$t1->join;
$t2->join;

print "$common\n";

#
# Perl 5.8 スレッドの変数共有テスト
#
use threads 'async';
use threads::shared;

my $common : shared = 0;

$t1 = async {
my $tid = threads->self->tid;
print "thread $tid\n";

$common++;
};

$t2 = async {
my $tid = threads->self->tid;
print "thread $tid\n";

$common++;
};


$t1->join;
$t2->join;

print "$common\n";