20
その sleep 、ちょっと待った! OGATA Tetsuji (@xtetsuji) 2014/0 5/23 PerlBeginners#13

そのsleep、ちょっと待った! #perlbeginners

Embed Size (px)

DESCRIPTION

2014/5/23に行われた PerlBeginners#13 で発表したLTのスライドです。

Citation preview

Page 1: そのsleep、ちょっと待った! #perlbeginners

そのsleep、ちょっと待った!OGATA Tetsuji (@xtetsuji)

2014/05/23 PerlBeginners#13

Page 2: そのsleep、ちょっと待った! #perlbeginners

自己紹介

• 尾形 鉄次 (OGATA Tetsuji)

• Twitter: @xtetsuji

• Blog: http://post.tetsuji.jp/

Page 3: そのsleep、ちょっと待った! #perlbeginners

sleep

Page 4: そのsleep、ちょっと待った! #perlbeginners

通院スペシャリスト

• 昨年12月に胃潰瘍で入院、1月に風邪とインフルエンザ

• 今も入院していた消化器外科に通院しているのですが、ここ最近は咳も止まらなくて呼吸器内科にも通い始めた

• 結果、薬が増えまくった

Page 5: そのsleep、ちょっと待った! #perlbeginners
Page 6: そのsleep、ちょっと待った! #perlbeginners

テーマをsleepにした理由

• 呼吸器内科の薬の副作用だと思うけど、眠くて困る

• 今回のPBも最初は発表者がいなくて「じゃあ僕も何かしゃべりますよ」って言ったけど、テーマを考えている最中も眠くて参った

• というわけでテーマをsleepにしました

Page 7: そのsleep、ちょっと待った! #perlbeginners

最初のsleep体験

• (高校時代のMSX BASICのことはもう記憶に無いなぁ)

• 大学一年生の時のC言語の授業

• なんか「ちょっと待ってから出力」したいというときにこういうコードを例示された覚えがある

Page 8: そのsleep、ちょっと待った! #perlbeginners

最初のsleep体験#include <stdio.h>!!

int main (void) {! int i;! printf("こんにちは!\n");! for(i=0;i<1000000000;i++) {}! printf("待った?\n");! return(1);!}!

Page 9: そのsleep、ちょっと待った! #perlbeginners

CPU温めsleep• for文で無駄な計算をさせて、処理を遅らせるハック!?

• CPUが暖まって冬に嬉しい、夏に厳しい

• 賢いコンパイラには最適化されて無意味になるはず

• POSIX系OSであればunistd.hにsleep関数あります

• こういう悪手、JavaScriptで「待ちたい」というときに似たような手法やる人いそうでヤバイときがある

Page 10: そのsleep、ちょっと待った! #perlbeginners

Perlのsleep• Perlにはsleepという関数が標準関数で存在する!

• sleepし放題

• だけど、あまりsleepしてはダメな時がある

• ウェブサーバのような即時応答が基本なもの

• イベント駆動サーバのように他の処理をブロックしてはいけないもの、などなど…

Page 11: そのsleep、ちょっと待った! #perlbeginners

同期とかブロッキングとか

• sleepのように、同じプロセス上で同時並行で走っているかもしれない他の処理を阻害する処理のことを「同期」処理とか「ブロッキング」処理とかいいます

• 対義語は「非同期」「ノンブロッキング」

• 同期・非同期とブロッキング・ノンブロッキングの違いはここではあまり厳密に区別しません

Page 12: そのsleep、ちょっと待った! #perlbeginners

Webサーバでちょっと待ちたい• sleepとか書くと、ワーカーの同時処理を阻害する

• Mojoliciousのhypnotoadでは標準でワーカーは4しかいないので、長時間ブロックする処理が4連続続いたら、しばらくはWebサーバが無反応になる

• Plackで使われるStarmanやStarletもだいたい同じ

• 待ちたい場合には別の書き方をする

Page 13: そのsleep、ちょっと待った! #perlbeginners

そもそもなぜ待ちたいのか

• ユーザに遅延してデータを送りたいってケース、まれにあるかもしれないけど、よくよく考えると別レイヤーでやった方が良いケースがある(ブラウザ上のJavaScript等)

• JavaScriptは非同期前提の世界なので、そういう考え方が鍛えられます

Page 14: そのsleep、ちょっと待った! #perlbeginners

API制限とか• 単位時間あたりのAPIリクエスト数に制限があるから

sleepするとかってケース(外部に気を使うケース)

• AnyEventなどのイベント駆動サーバ上で動いているものの場合はsleepって書くと他の部分を止めることになるので禁じ手だし、LWPだってブロッキング処理だって、神経質な人に言われるかも (AnyEvent::HTTP使う等する)

• 戦場に備えてsleepしない書き方を覚えておくと良い

Page 15: そのsleep、ちょっと待った! #perlbeginners

逆に同時並行アクセスとか• 逆に一度のHTTPリクエストに対して、何度もLWPを使って外へHTTPアクセスする必要がある場合、LWPの多用自体が無視できないブロッキングになる場合がある

• RSSとかのクローラみたいなやつ

• HTTP::Async とか “Parallel HTTP” で検索して出てくるCPANモジュールを使うと同時並行アクセスができる事を覚えておくと、いざというときに役に立つ

Page 16: そのsleep、ちょっと待った! #perlbeginners

余談:JavaScriptでは• 非同期前提のJavaScriptの世界ではsleepは無い

• 最初のfor文のようなユーザのCPUを温めるコードを書いたらマジでクレームもの

• setTimeoutなどを利用したり、HTTPアクセスではAjaxの非同期モードを使うのが前提

• 順序を気にする場合にはDeferredとかで検索してみよう

Page 17: そのsleep、ちょっと待った! #perlbeginners

書き捨てならOKだよ

• もちろん、書き捨てスクリプトならsleepでもよいよね

• 「仕方なく一瞬待つ」場合はTime::HiResで可能な限り影響を少なくする

• 今日はトークレベルや時間の都合で、結構端折っちゃったけど、サーバのライフサイクルとか興味のある人は、他の書籍や勉強会で調べてみるといいですよ

Page 18: そのsleep、ちょっと待った! #perlbeginners

そのsleep、ちょっと待った! →待ち方が問われる場合アリ!

Page 19: そのsleep、ちょっと待った! #perlbeginners

眠くなってきたので このへんで、おやすみなさい😪

Page 20: そのsleep、ちょっと待った! #perlbeginners

おしまい