Upload
tetsuji-ogata
View
3.319
Download
0
Embed Size (px)
DESCRIPTION
2014/5/23に行われた PerlBeginners#13 で発表したLTのスライドです。
Citation preview
そのsleep、ちょっと待った!OGATA Tetsuji (@xtetsuji)
2014/05/23 PerlBeginners#13
自己紹介
• 尾形 鉄次 (OGATA Tetsuji)
• Twitter: @xtetsuji
• Blog: http://post.tetsuji.jp/
sleep
通院スペシャリスト
• 昨年12月に胃潰瘍で入院、1月に風邪とインフルエンザ
• 今も入院していた消化器外科に通院しているのですが、ここ最近は咳も止まらなくて呼吸器内科にも通い始めた
• 結果、薬が増えまくった
テーマをsleepにした理由
• 呼吸器内科の薬の副作用だと思うけど、眠くて困る
• 今回のPBも最初は発表者がいなくて「じゃあ僕も何かしゃべりますよ」って言ったけど、テーマを考えている最中も眠くて参った
• というわけでテーマをsleepにしました
最初のsleep体験
• (高校時代のMSX BASICのことはもう記憶に無いなぁ)
• 大学一年生の時のC言語の授業
• なんか「ちょっと待ってから出力」したいというときにこういうコードを例示された覚えがある
最初のsleep体験#include <stdio.h>!!
int main (void) {! int i;! printf("こんにちは!\n");! for(i=0;i<1000000000;i++) {}! printf("待った?\n");! return(1);!}!
CPU温めsleep• for文で無駄な計算をさせて、処理を遅らせるハック!?
• CPUが暖まって冬に嬉しい、夏に厳しい
• 賢いコンパイラには最適化されて無意味になるはず
• POSIX系OSであればunistd.hにsleep関数あります
• こういう悪手、JavaScriptで「待ちたい」というときに似たような手法やる人いそうでヤバイときがある
Perlのsleep• Perlにはsleepという関数が標準関数で存在する!
• sleepし放題
• だけど、あまりsleepしてはダメな時がある
• ウェブサーバのような即時応答が基本なもの
• イベント駆動サーバのように他の処理をブロックしてはいけないもの、などなど…
同期とかブロッキングとか
• sleepのように、同じプロセス上で同時並行で走っているかもしれない他の処理を阻害する処理のことを「同期」処理とか「ブロッキング」処理とかいいます
• 対義語は「非同期」「ノンブロッキング」
• 同期・非同期とブロッキング・ノンブロッキングの違いはここではあまり厳密に区別しません
Webサーバでちょっと待ちたい• sleepとか書くと、ワーカーの同時処理を阻害する
• Mojoliciousのhypnotoadでは標準でワーカーは4しかいないので、長時間ブロックする処理が4連続続いたら、しばらくはWebサーバが無反応になる
• Plackで使われるStarmanやStarletもだいたい同じ
• 待ちたい場合には別の書き方をする
そもそもなぜ待ちたいのか
• ユーザに遅延してデータを送りたいってケース、まれにあるかもしれないけど、よくよく考えると別レイヤーでやった方が良いケースがある(ブラウザ上のJavaScript等)
• JavaScriptは非同期前提の世界なので、そういう考え方が鍛えられます
API制限とか• 単位時間あたりのAPIリクエスト数に制限があるから
sleepするとかってケース(外部に気を使うケース)
• AnyEventなどのイベント駆動サーバ上で動いているものの場合はsleepって書くと他の部分を止めることになるので禁じ手だし、LWPだってブロッキング処理だって、神経質な人に言われるかも (AnyEvent::HTTP使う等する)
• 戦場に備えてsleepしない書き方を覚えておくと良い
逆に同時並行アクセスとか• 逆に一度のHTTPリクエストに対して、何度もLWPを使って外へHTTPアクセスする必要がある場合、LWPの多用自体が無視できないブロッキングになる場合がある
• RSSとかのクローラみたいなやつ
• HTTP::Async とか “Parallel HTTP” で検索して出てくるCPANモジュールを使うと同時並行アクセスができる事を覚えておくと、いざというときに役に立つ
余談:JavaScriptでは• 非同期前提のJavaScriptの世界ではsleepは無い
• 最初のfor文のようなユーザのCPUを温めるコードを書いたらマジでクレームもの
• setTimeoutなどを利用したり、HTTPアクセスではAjaxの非同期モードを使うのが前提
• 順序を気にする場合にはDeferredとかで検索してみよう
書き捨てならOKだよ
• もちろん、書き捨てスクリプトならsleepでもよいよね
• 「仕方なく一瞬待つ」場合はTime::HiResで可能な限り影響を少なくする
• 今日はトークレベルや時間の都合で、結構端折っちゃったけど、サーバのライフサイクルとか興味のある人は、他の書籍や勉強会で調べてみるといいですよ
そのsleep、ちょっと待った! →待ち方が問われる場合アリ!
眠くなってきたので このへんで、おやすみなさい😪
おしまい