Your SlideShare is downloading. ×
0
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
マルチタスクって奥が深い #mishimapm
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

マルチタスクって奥が深い #mishimapm

6,057

Published on

2014/7/12に行われた Mishima.pm#1 で発表したトークのスライドです。

2014/7/12に行われた Mishima.pm#1 で発表したトークのスライドです。

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
6,057
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. マルチタスクって奥が深い OGATA Tetsuji (@xtetsuji) 2014/07/12 Mishima.pm#1
  • 2. 自己紹介 • 尾形 鉄次 (OGATA Tetsuji) • Twitter: @xtetsuji • Blog: http://post.tetsuji.jp/
  • 3. 今回は無事に静岡に来られた!
  • 4. 2013/12/11 Mishima.pm#0 2013年12月に胃潰瘍で入院したときのツイートまとめ - Togetterまとめ http://togetter.com/li/607049
  • 5. あれから半年 • 半年経過後の胃カメラ検査をつい先日してきました • 静岡前の胃カメラ、今度は死亡フラグじゃなかった • 珍しい位置の潰瘍だったけど、なんとか生きてます • あれから毎月激動で、公私ともに忙しいけれど、皆様の 温かいご支援で生きています
  • 6. 今だから復習したい マルチタスク
  • 7. 過去にもマルチタスクの話は 結構しているけど成長が(ry
  • 8. 過去にしているトークの一例 • 「そのsleep、ちょっと待った」(PerlBeginners#13) • 「イベント駆動とノンブロッキング」(Hokkaido.pm#10) • 今回はこれらのプラスアルファな感じの話をします • ビギナー向けにちょうどよい感じ、という言い訳 • みんなで質疑応答をしたりといった感じでよろしくです
  • 9. 色々なPerlのツール • forkや、Parallel::ForkManager、Parallel::Prefork など • 封印されしithreads (アッ、誰か来た) • AnyEvent前史のPOEフレームワーク • AnyEvent、そしてCoroといったMarc Lehmmanツール • 今昔IO非同期系ツール群
  • 10. 結構雑にカジュアルに • マルチタスク=複数の仕事をこなす • 非同期=ノンブロッキング • 同期=ブロッキング • 情報系の学術論文でないのであれば、この辺りあんまり 厳密に区別しなくてもよいっぽい(頭の中でできることに 越した事はありません)
  • 11. ithreadsが使われない理由 • Perlのスレッド(ithreads)は不安定だし効率が悪い • Perlはグローバルな状態だらけの世界観なので、後付け のスレッドもインタープリタプールを作ったり、色々大 変な事をしているので、同情してあげてください • Windowsにはforkがないので、WindowsのPerlでは Win32スレッドを使ったforkのエミューレーションをし ているそうです
  • 12. forkモデル • fork=フォーク=分岐 • 途中で親と子に分かれてプログラムの分岐を行う • Perl組み込みのfork関数がそれを実現してくれる
  • 13. forkサンプル #!/usr/bin/env perl! ! use strict;! use warnings;! use utf8;! ! binmode STDOUT, ':utf8';! binmode STDERR, ':utf8';! ! print "親です。プロセスIDは $$ です。開始します。n";! ! my $pid = fork; # ここで親と子で分岐! ! if ( $pid ) {! sleep 2;! print "親です。子のプロセスIDは $pid のようです。しばらく休みますn";! sleep 10;! print "親です。10秒待ちました。n";! } elsif ( $pid == 0 ) {! sleep 3;! print "子です。私のプロセスIDは $$ のようです。n";! for my $i (1..5) {! print "子です。${i}回目。n";! sleep 1;! }! print "子はしばらく待ちます。先に親が終了してプロンプトに戻りますn";! sleep 10;! } else {! die "forkできなかった?n";! }! ! print "pid=$pid $$=$$n"; # 親も子も通る
  • 14. あんまりforkを直接書かない • 見てパッと理解できない • 多くの子プロセスを作るときにfork()を呼びまくった ら結構混乱する • 親と子でコミュニケーションするにはプロセス間通信が 一番プリミティブな方法かな • 多くのforkが必要になった場合には、これを抽象化した Parallel::ForkManagerが役に立つ
  • 15. Parallel::ForkManagerの例 #!/usr/bin/env perl! ! use strict;! use warnings;! ! use LWP::UserAgent;! use Parallel::ForkManager;! ! my @urls = ( map { sprintf "http://example.jp/images/%02d.jpg" } (1..99) );! ! my $ua = LWP::UserAgent->new;! ! my $pm = Parallel::ForkManager->new(5); # 最大5プロセス並列! ! for my $url (@urls) {! my $pid = $pm->start and next;! # 子プロセスの処理! print "プロセスIDが $$ の子プロセスが $url からデータをダウンロードしますn";! ( my $filename = $url ) =~ s{.*/}{};! $ua->get($url, ":content_file" => $filename);! $pm->finish; # 子プロセスを終了! }
  • 16. 並列ダウンロードと マルチタスク • 外界の影響を受けるダウンロードというタスクの場合、 同期的にダウンロードをするとサーバによって待たされ るケースがあったりする • RSSとかを大量にクロールするとか、死活問題 • 例えばParallel::ForkManagerで解決できる
  • 17. ForkManagerとPrefork • Parallel::ForkManagerは並列クライアントを作るもの、 Parallel::Preforkは並列処理ができるforkモデルのサーバ を作るものと覚えておくとよい • Parallel::ForkManagerは相当以前からDebian/Ubuntu パッケージとしても提供されているので、システムPerl でも使いやすい • Parallel::Preforkは奥一穂さんによる和製モジュール
  • 18. forkの問題点と言われること • プログラムのコピーなのでメモリを食う • Copy on Write(CoW)というOSの機構により倍々には ならないはずだけど、限界はある • プロセス間通信が面倒 • これは頑張るか、コストを気にしなければHTTP等の サーバを介したりするのがよいかも
  • 19. とはいえforkはよく使う • UNIX/Linuxのサブプロセスの原点fork • 覚えておくと色々勉強になるし、自分もよく勉強してる • Perlのsystem関数はforkとexecの組み合わせ • 先輩プログラマが「フォーク」とか言っているときに、 ちょっと知った気になれるの重要
  • 20. イベント駆動モデル • スレッドともforkとも若干違うマルチタスクモデル • Apacheのprefork MPMがAjax時代にまつわるC10K問題 に対抗できない代替として生まれたともいえるNginxの マルチタスクモデルとして注目された • Perlでは、AnyEventというイベント駆動フレームワーク が以前から主流で、以前からあった同種のイベント駆動 モジュールのインターフェースを統一したりもした
  • 21. AnyEvent • 以前流行したPOEの後継にあたるものともいえる • Perlで動作する様々なイベント駆動フレームワークの、 今の事実上のデファクトスタンダード • 裏側のイベント処理実装に様々なものが選べる • 各種イベント(時間、I/O、シグナル、などなど)で処理を 走らせることができる
  • 22. AnyEventの後ろの実装 • AnyEvent::Impl::* 以下にあるものが選べる • Cocoa、Event、FLTK、IOAsync、POE、Qt、EV、 EventLib、Glib、Irssi、Perl (AnyEvent標準の実装)、Tk • 通常はAnyEvent::Impl::Perlが選ばれるけど、EVを選ん だり、場所によって選択を変える場合がある • Marc Lehmann氏も「POEはやめとけ」と書いている
  • 23. POEが衰退した理由 • 構造が複雑:OSとほぼ同じ、カーネル・ヒープ構造 • 書き方が複雑 • 静かにプログラムが異常終了していることが多かった • 重いとも言われていた
  • 24. daemonを作るwhileループ • daemon的な常駐プログラムを作る場合、
 while(1){…} といった無限ループを作ることが定石 • とはいえ、無限ループにsleepをはさみ忘れたりすると、 CPU暴走してサーバが死んだりするので怖い • while無限ループはなるべく自前で書かない方がいいとい うのが私の持論
  • 25. AnyEventの方法論 • AnyEvent::Impl::* によっても変わるけど、結局的に、 PerlやCのwhile(1){…}が一番根底で走っていると思っ て差し支えない • 特にAnyEvent::Impl::Perlの場合は、AnyEvent::Loopが それらしい
  • 26. AnyEvent::Loopより sub run {! one_event while 1;! } one_event メソッドは多くの仕事をしていますが割愛
  • 27. AnyEventの活用例 • クライアントでは各種IRCやTwitterボットなどで活用 • サーバではWebサーバ(Twiggyが有名)をはじめとした、 任意のTCPサーバが書ける • これらを組み合わせたりできるので、IRCクライアント でかつWebサーバというプログラムも書ける (Ikachanと いう良い実装例もある)
  • 28. AnyEventで時間イベント #!/usr/bin/env perl! ! use strict;! use warnings;! use AnyEvent;! ! my $cv = AnyEvent->condvar; # 状態変数! my $timer1 = AnyEvent->timer(! after => 1,! cb => sub { print "timer1 hello!n"; },! interval => 2,! );! my $timer2 = AnyEvent->timer(! after => 1,! cb => sub { print "timer2 hello!n"; },! interval => 3,! );! my $timer3 = AnyEvent->timer(! after => 1,! cb => sub { print "timer3 hello!n"; },! interval => 5,! );! my $stop_timer = AnyEvent->timer(! after => 10,! cb => sub { $cv->send("end"); }, # 終わらせる! );! my $val = $cv->recv; # ループをまわす! print "terminate: $valn";
  • 29. AnyEventで時間イベント • 最初はwhileループのほうが良いと思うけど、自分で気を つけてsleep書かなくてもいいし慣れるとこっちが良い • IRCボットとかだと、定時発言などもこれでできる • perldoc AnyEventをみたり、CPANでAnyEventで作られ たモジュールを見たりして少しずつ覚えていくといい
  • 30. AnyEvent::Mac::Pasteboard • Macのクリップボード(ペーストボード)を監視して、変更 があったら指定の処理をするモジュールを書いてみた • これもタイマーで変更を定期監視しているだけ • Cocoaの知識があればもっと良い感じができるかも • その後AnyEvent::Clipboardも作りました(GitHub止まり)
  • 31. その他 • CPANで「Async」というキーワードで検索してみる • AnyEventを入れるほどではないけど、非同期アクセスが 必要な場合に良い場合がある (HTTP::Asyncとか) • MojoliciousであればMojo::IOLoopとか • Mojolicious飲み会とかやりたいと思っているので、続き はそこで非同期飲み会やりましょう
  • 32. 注意点とか • LWP::UserAgent等で長時間処理をブロックしたりする と、AnyEventの処理全体をブロックすることになるので ノンブロッキングなAnyEvent::HTTPなどを使おう • JavaScriptのAjaxやっている人だとコールバック的 • ドヤ顔で「AnyEventで(ry」とか言ってIO::Socket::INET 使っていたりすると、ブロッキングとか言われて恥ずか しい思いをします
  • 33. 最後にいろいろ • ノンブロッキングのネットワークI/Oについては AnyEvent::Socketをベースに作ります • AnyEvent::SocketはSocketモジュールをベースに、ノン ブロッキングネットワークI/Oの方法論を元に書かれてい るようです • 基本的に、既に作られているL7層のモジュールを元に、 自分で新しいプログラムやモジュールを作ればしあわせ
  • 34. 全然掘り起こせなかったですが 奥が深いので続きはどこかで
  • 35. おしまい

×