Upload
maka2donzoko
View
59
Download
0
Embed Size (px)
Citation preview
どーも
サイリウムです
自己紹介:
名前:まかまか(略
所属:ネコトーストラボ
出典:http://free-designer.net/serach/entry.php?id=19151
出典:http://bkuma.hatena.ne.jp/entry/iseebitarou.ldblog.jp/archives/24311566.html
今日はこういう
「もう使われなくなる 懐かしいもの」
の話です。
Perlの
ithreads(iスレッド)
Perlではスレッドプログラミングをするためにithreadsがある(あった)
スレッド……プロセスより軽いあれ
usethreadオプションを
つけてPerlをコンパイル
use threads;
threads->new( sub {
say 'Hello in ', threads->tid
} )->detach for 1 .. 10;
say 'Hello in ' , threads->tid; # メインスレッドtid=0
say 'end.';
Hello in 1
Hello in 2
Hello in 3
Hello in 4
Hello in 5
Hello in 6
Hello in 7
Hello in 8
Hello in 0
end.
Hello in 10
Hello in 9
Perl 5.20で
ithreadsの利用は
discouragedになった
わが青春の愛スレッド
~さよなら哀スレッド
来歴
元々はWindows版Perlでforkをエミュレートするためのもの(Win32 Thread)
それが逆輸入されpthreadで実装された
※5.5時代はThreadというモジュールがあった(5005threads)。
動作原理
threads->new(\&foo) するとpthread_createされて&fooを実行するperlインタプリタが生成される。
threads->new(\&foo) するとpthread_createされて&fooを実行するperlインタプリタが生成される。
そして親スレッドの一切合財(シンボルテーブル、変数、ファイル)が子スレッドにコピーされる。
threads->new(\&foo) するとpthread_createされて&fooを実行するperlインタプリタが生成される。
そして親スレッドの一切合財(シンボルテーブル、変数、ファイル)が子スレッドにコピーされる……
my $hoge;
threads->create(sub{ })->detach;
# ↑スレッド内に$hogeはコピーされている!
my $hoge;
threads->create(sub{ })->detach;
# ↑スレッド内に$hogeはコピーされている!
threads->create(sub{ })->detach;
# ↑こっちでも!
大抵のスレッドの売り「軽い」
大抵のスレッドの売り「軽い」
ithreads……「重い」
大抵のスレッドの売り「軽い」
ithreads……「重い」
※メモリ的及び速度的に
コーディングのコツ:
何もuseしてない、変数宣言してない段階で必要なだけ予めスレッドを生成しておくとよい!
use threads;
my @threads;
push @threads, threads->new(\&foo) for 1..100;
# ここからくそ大量のモジュールをuseする
use DBIx::Class;
...
変数値の共有動作原理
変数は悉くコピーされるので、変数がスレッド間で共有されることはない
use threads;
my $foo = 1;
my $thr = threads->new(sub { $foo++ });
$thr->join;
say $foo; # => 1
そこで
threads::shared
use threads;
use threads::shared;
my $foo : shared = 1;
my $thr = threads->new(sub { $foo++ });
$thr->join;
say $foo; # => 2
use threads;
use threads::shared;
share($foo);
my $thr = threads->new(sub { $foo++ });
$thr->join;
say $foo; # => 2
ちなみにblessされたオブジェクトがあれば子スレッドの数だけDESTROYが呼ばれるよ!
use threads;
use threads::shared;
my $foo = bless {}, 'Foo';
my $thr = threads->new(sub {})->detach;
package Foo;
sub DESTROY {
say 'Destroy! ', threads->tid;
}
Destroy! 0
Destroy! 1
変数がスレッド間で共有されることがないので既存のコードも安心!
変数がスレッド間で共有されることがないので既存のコードも安心! →PurePerlなら……
XSモジュールについてはその限りではないので、スレッドセーフかどうかは一つひとつチェックしないと。
CLONEサブルーチン使う。
sub CLONE { }
shareされた変数は裏ではtieされ、「共有変数用スレッド」にリンクされる。
shareされた変数は裏ではtieされ、「共有変数用スレッド」にリンクされる。
STOREやFETCHを通じてデータがやり取りされる!
→遅い!
共有変数用スレッドスレッドA スレッドB
$foo = 1
say $foo
$foo
コンテキスト動作原理
new (create) した時のコンテキストがjoin時のコンテキストになる。
use threads;
my $th1 = threads->new( sub{return 1,3,5;} );
say $th1->join; # => 5
my ($th2) = threads->new( sub{return 1,3,5;} );
say $th2->join; # => 135
ithreads
進化の過程
初期の頃は
threads->new
に失敗するといきなりperlごと死ぬ
$thr->is_joinable
$thr->is_detached
$thr->is_running
などのメソッドがなかった
スレッド用exitはない
子スレッド内でexitするとperlごとexitする
その他昔の色々は下記サイトにhttp://www.donzoko.net/doc/memo/perlithreads.html
なぜか
みんなPurePerlで頑張った
Thread::State
Thread::Running
Thread::Running
threads::newを上書きしてスレッドを生成するときに共有クラス変数に状態を記録する
Thread::Exit
Thread::Exit
CORE::GLOBAL::exitを上書きしてごにょごにょ……
Thread::State
Thread::State
- XSモジュールis_joinable
is_joined
is_detached
wantarray
priority
現在これらは
コアで実装されてます
V1.09
スタックサイズの設定が可能に
スレッドIDが64bit整数に
V1.27
$thr->killでシグナル可能に
V1.33
exitで子スレッド終了
$thr->exit実装
V1.34
->is_running, ->is_detached, ->is_joinable, ->wantarray
実装
~ V2.02
この間、絶えずメモリリークとクラッシュを減じてきている
ithreads
の天敵
ithreads重くて不安定だよね……
プロセスで
よいのでは?
forks
use forks;
threads->new( sub {
say 'Hello in ', threads->tid
} )->detach for 1 .. 10;
say 'Hello in ' , threads->tid; # メインスレッドtid=0
say 'end.';
Marc Lehmann先生
Marc Lehmann先生
Coro
Marc Lehmann先生Unlike the so-called "Perl threads" ..., Coro provides a full shared address space, which makes communication between threads very easy. And coro threads are fast, too
しかしCoroは
Perl 5.22で動かなくなった!
ない
ありがとうithreads
さようならithreads
わが青春の愛スレッド
~さよなら哀スレッド