Upload
gosuke-miyashita
View
9.832
Download
1
Embed Size (px)
DESCRIPTION
2年ぐらい前の社内勉強会で使った資料。
Citation preview
イベント駆動プログラミングと
I/O多重化
イベント駆動プログラミング
イベントを待機し、起こったイベントに従って処理を行うプログラミングパラダ
イム
フロー駆動型プログラミングと呼ばれる従来のプログラミングパラダイムに対す
る概念
GUIプログラミング
キーやマウスの入力をイベントとして受け取って処理
ネットワークプログラミング
ネットワーク I/Oを多重化して1プロセス 1スレッドで複数のネットワーク接続を同時に捌
く
非イベント駆動なネットワークプログラミング
processor
thread
processor
thread
processor
thread
Client
Client
Client
イベント駆動なネットワークプログラミング
processor
thread
Client
Client
Client
今回はこっちがメイン
The C10K Problem
イベント駆動型プログラミングの処理フ
ロー
element.addEventListener( ’click’, function(){ console.log(‘hoge’) }, true);
これってどう動いてるの?
イベントループ(メインループ)
イベント待ち
イベント処理
後処理
イベント登録
高レベルな言語ではイベントループを自分で書く必要はない
element.addEventListener( ’click’, function(){ console.log(‘hoge’) }, true);
後で自分で書くとどうなるか解説します
イベントの種類
タイマー
I/O
シグナル
子プロセス
イベント待ち
イベント処理
後処理
イベント登録
イベントループの話おしまい
I/O多重化
ネットワークプログラミングにおけるイベント駆
動の要
これなくして 1プロセス 1スレッドで複数のネットワーク接続を同時捌くこと
はできない
なぜ 1プロセス 1スレッドで捌く必要があるの
か?
The C10K Problemでググれ
I/O多重化の仕組み
I/Oイベント待ち
I/Oイベント処理
後処理
I/Oイベント登録
非同期 echoサーバを題材にサンプルコードで見
る
多重化してない例
int sock = socket(PF_INET, SOCK_STREAM);bind(sock, addr);listen(sock);
while ( 1 ) { int new_sock = accept(sock, &addr); char buf[100]; size_t size = read(new_sock, buf, 100); if ( size == 0 ) { close(new_sock); } else { write(new_sock, buf, size); }}
多重化での処理の流れ
サーバ
クライアント
待ち受けソケット(イベント監視対象につっこむ)
サーバ
クライアント
待ち受けソケット(イベント監視対象)
サーバ
クライアント
待ち受けソケット(イベント監視対象)
接続ソケット(イベント監視対象につっこむ)
accept(sock)
サーバ
クライアント
待ち受けソケット(イベント監視対象)
接続ソケット(イベント監視対
象)
selectによる多重化
https://gist.github.com/mizzy/5343931
epollによる多重化
https://gist.github.com/mizzy/5343937
多重化用関数
selectpoll
epollkqueue
/dev/poll
select/pollは全部のソケットを調べる
epoll, kqueue, /dev/pollはイベントが発生したソケットだけを調べることができる
イベントライブラリ
libeventlibev
OSによる違いを吸収してくれる
I/O多重化以外にもタイマーイベントやシグナルイベントなんかも扱える
node.jsはlibevent + libeio
各種言語による非同期 echoサーバ
Perl(AnyEvent)
https://gist.github.com/mizzy/5343944
Ruby(EventMachine)
https://gist.github.com/mizzy/5343953
Python(twisted)
https://gist.github.com/mizzy/5343956
Python(eventlet)
https://gist.github.com/mizzy/5343959
node.js
https://gist.github.com/mizzy/5343964
イベント駆動プログラミングのデメリット
マルチコアでスケールしない
処理の流れが追いにくい書きにくい
var req_to_zenrin = http.request( options, function(res2) { res2.on('end', function() { res.end(); }); res2.on('data', function(chunk) { res.write(chunk); }); });
var referer;sdb.getItem( 'gha', host, function( error, result ) { if ( result ) { referer = ‘http://hoge.com/’; } });
// sdb.getItem()終了前に次の処理
sdb.getItem( 'gha', host, function( error, result ) { if ( result ) { access_to_zenrin('http://hoge.com'); } else { access_to_zenrin(); } });
ネットワークアクセスを伴う
処理をすべて非同期で書かないといけない
なので libmysqlclientは使えない
node-mysqlは libmysqlclient相当の処理を再実装してる
(っぽい)
参考文献