80
リジェクトコン 2015 2015-09-11 まかまか般若波羅蜜 [email protected] Twitter: @maka2_donzoko

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

Embed Size (px)

Citation preview

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

リジェクトコン2015

2015-09-11 まかまか般若波羅蜜[email protected]

Twitter: @maka2_donzoko

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

どーも

サイリウムです

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

自己紹介:

名前:まかまか(略

所属:ネコトーストラボ

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

出典:http://free-designer.net/serach/entry.php?id=19151

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

出典:http://bkuma.hatena.ne.jp/entry/iseebitarou.ldblog.jp/archives/24311566.html

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

今日はこういう

「もう使われなくなる 懐かしいもの」

の話です。

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

Perlの

ithreads(iスレッド)

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

Perlではスレッドプログラミングをするためにithreadsがある(あった)

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

スレッド……プロセスより軽いあれ

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

usethreadオプションを

つけてPerlをコンパイル

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

use threads;

threads->new( sub {

say 'Hello in ', threads->tid

} )->detach for 1 .. 10;

say 'Hello in ' , threads->tid; # メインスレッドtid=0

say 'end.';

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

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

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

Perl 5.20で

ithreadsの利用は

discouragedになった

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

わが青春の愛スレッド

 ~さよなら哀スレッド

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

来歴

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

元々はWindows版Perlでforkをエミュレートするためのもの(Win32 Thread)

それが逆輸入されpthreadで実装された

※5.5時代はThreadというモジュールがあった(5005threads)。

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

動作原理

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

threads->new(\&foo) するとpthread_createされて&fooを実行するperlインタプリタが生成される。

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

threads->new(\&foo) するとpthread_createされて&fooを実行するperlインタプリタが生成される。

そして親スレッドの一切合財(シンボルテーブル、変数、ファイル)が子スレッドにコピーされる。

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

threads->new(\&foo) するとpthread_createされて&fooを実行するperlインタプリタが生成される。

そして親スレッドの一切合財(シンボルテーブル、変数、ファイル)が子スレッドにコピーされる……

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

my $hoge;

threads->create(sub{ })->detach;

# ↑スレッド内に$hogeはコピーされている!

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

my $hoge;

threads->create(sub{ })->detach;

# ↑スレッド内に$hogeはコピーされている!

threads->create(sub{ })->detach;

# ↑こっちでも!

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

大抵のスレッドの売り「軽い」 

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

大抵のスレッドの売り「軽い」 

ithreads……「重い」

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

大抵のスレッドの売り「軽い」 

ithreads……「重い」

 ※メモリ的及び速度的に

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

コーディングのコツ:

何もuseしてない、変数宣言してない段階で必要なだけ予めスレッドを生成しておくとよい!

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

use threads;

my @threads;

push @threads, threads->new(\&foo) for 1..100;

# ここからくそ大量のモジュールをuseする

use DBIx::Class;

...

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

変数値の共有動作原理

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

変数は悉くコピーされるので、変数がスレッド間で共有されることはない

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

use threads;

my $foo = 1;

my $thr = threads->new(sub { $foo++ });

$thr->join;

say $foo; # => 1

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

そこで

threads::shared

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

use threads;

use threads::shared;

my $foo : shared = 1;

my $thr = threads->new(sub { $foo++ });

$thr->join;

say $foo; # => 2

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

use threads;

use threads::shared;

share($foo);

my $thr = threads->new(sub { $foo++ });

$thr->join;

say $foo; # => 2

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

ちなみにblessされたオブジェクトがあれば子スレッドの数だけDESTROYが呼ばれるよ!

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

use threads;

use threads::shared;

my $foo = bless {}, 'Foo';

my $thr = threads->new(sub {})->detach;

package Foo;

sub DESTROY {

say 'Destroy! ', threads->tid;

}

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

Destroy! 0

Destroy! 1

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

変数がスレッド間で共有されることがないので既存のコードも安心!

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

変数がスレッド間で共有されることがないので既存のコードも安心! →PurePerlなら……

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

XSモジュールについてはその限りではないので、スレッドセーフかどうかは一つひとつチェックしないと。

CLONEサブルーチン使う。

sub CLONE { }

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

shareされた変数は裏ではtieされ、「共有変数用スレッド」にリンクされる。

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

shareされた変数は裏ではtieされ、「共有変数用スレッド」にリンクされる。

STOREやFETCHを通じてデータがやり取りされる!

 →遅い!

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

共有変数用スレッドスレッドA スレッドB

$foo = 1

say $foo

$foo

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

コンテキスト動作原理

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

new (create) した時のコンテキストがjoin時のコンテキストになる。

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

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

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

ithreads

進化の過程

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

初期の頃は

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

threads->new

に失敗するといきなりperlごと死ぬ

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

$thr->is_joinable

$thr->is_detached

$thr->is_running

などのメソッドがなかった

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

スレッド用exitはない

子スレッド内でexitするとperlごとexitする

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

その他昔の色々は下記サイトにhttp://www.donzoko.net/doc/memo/perlithreads.html

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

なぜか

みんなPurePerlで頑張った

Thread::State

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

Thread::Running

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

Thread::Running

threads::newを上書きしてスレッドを生成するときに共有クラス変数に状態を記録する

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

Thread::Exit

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

Thread::Exit

CORE::GLOBAL::exitを上書きしてごにょごにょ……

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

Thread::State

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

Thread::State

 - XSモジュールis_joinable

is_joined

is_detached

wantarray

priority

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

現在これらは

コアで実装されてます

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

V1.09

スタックサイズの設定が可能に

スレッドIDが64bit整数に

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

V1.27

$thr->killでシグナル可能に

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

V1.33

exitで子スレッド終了

$thr->exit実装

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

V1.34

->is_running, ->is_detached, ->is_joinable, ->wantarray

実装

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

~ V2.02

この間、絶えずメモリリークとクラッシュを減じてきている

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

ithreads

の天敵

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

ithreads重くて不安定だよね……

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

プロセスで

よいのでは?

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

forks

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

use forks;

threads->new( sub {

say 'Hello in ', threads->tid

} )->detach for 1 .. 10;

say 'Hello in ' , threads->tid; # メインスレッドtid=0

say 'end.';

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

Marc Lehmann先生

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

Marc Lehmann先生

Coro

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

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

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

しかしCoroは

Perl 5.22で動かなくなった!

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

ない

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

ありがとうithreads

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

さようならithreads

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

わが青春の愛スレッド

 ~さよなら哀スレッド