リジェクトコン
2015
2015-09-11 まかまか般若波羅蜜
makamaka.donzoko@gmail.com
Twitter: @maka2_donzoko
どーも
サイリウムです
自己紹介:
名前:まかまか(略
所属:ネコトーストラボ
出典: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
わが青春の愛スレッド
 ~さよなら哀スレッド

Rejectcon2015 わが青春の愛スレッド~さよなら哀スレッド