78
イイイイイイイイイイイイイイ I/O イイイ

イベント駆動プログラミングとI/O多重化

Embed Size (px)

DESCRIPTION

2年ぐらい前の社内勉強会で使った資料。

Citation preview

Page 1: イベント駆動プログラミングとI/O多重化

イベント駆動プログラミングと

I/O多重化

Page 2: イベント駆動プログラミングとI/O多重化

イベント駆動プログラミング

Page 3: イベント駆動プログラミングとI/O多重化

イベントを待機し、起こったイベントに従って処理を行うプログラミングパラダ

イム

Page 4: イベント駆動プログラミングとI/O多重化

フロー駆動型プログラミングと呼ばれる従来のプログラミングパラダイムに対す

る概念

Page 5: イベント駆動プログラミングとI/O多重化

GUIプログラミング

Page 6: イベント駆動プログラミングとI/O多重化

キーやマウスの入力をイベントとして受け取って処理

Page 7: イベント駆動プログラミングとI/O多重化

ネットワークプログラミング

Page 8: イベント駆動プログラミングとI/O多重化

ネットワーク I/Oを多重化して1プロセス 1スレッドで複数のネットワーク接続を同時に捌

Page 9: イベント駆動プログラミングとI/O多重化

非イベント駆動なネットワークプログラミング

processor

thread

processor

thread

processor

thread

Client

Client

Client

Page 10: イベント駆動プログラミングとI/O多重化

イベント駆動なネットワークプログラミング

processor

thread

Client

Client

Client

Page 11: イベント駆動プログラミングとI/O多重化

今回はこっちがメイン

Page 12: イベント駆動プログラミングとI/O多重化

The C10K Problem

Page 13: イベント駆動プログラミングとI/O多重化

イベント駆動型プログラミングの処理フ

ロー

Page 14: イベント駆動プログラミングとI/O多重化

element.addEventListener( ’click’, function(){ console.log(‘hoge’) }, true);

Page 15: イベント駆動プログラミングとI/O多重化

これってどう動いてるの?

Page 16: イベント駆動プログラミングとI/O多重化

イベントループ(メインループ)

Page 17: イベント駆動プログラミングとI/O多重化

イベント待ち

イベント処理

後処理

イベント登録

Page 18: イベント駆動プログラミングとI/O多重化

高レベルな言語ではイベントループを自分で書く必要はない

Page 19: イベント駆動プログラミングとI/O多重化

element.addEventListener( ’click’, function(){ console.log(‘hoge’) }, true);

Page 20: イベント駆動プログラミングとI/O多重化

後で自分で書くとどうなるか解説します

Page 21: イベント駆動プログラミングとI/O多重化

イベントの種類

Page 22: イベント駆動プログラミングとI/O多重化

タイマー

Page 23: イベント駆動プログラミングとI/O多重化

I/O

Page 24: イベント駆動プログラミングとI/O多重化

シグナル

Page 25: イベント駆動プログラミングとI/O多重化

子プロセス

Page 26: イベント駆動プログラミングとI/O多重化

イベント待ち

イベント処理

後処理

イベント登録

Page 27: イベント駆動プログラミングとI/O多重化

イベントループの話おしまい

Page 28: イベント駆動プログラミングとI/O多重化

I/O多重化

Page 29: イベント駆動プログラミングとI/O多重化

ネットワークプログラミングにおけるイベント駆

動の要

Page 30: イベント駆動プログラミングとI/O多重化

これなくして 1プロセス 1スレッドで複数のネットワーク接続を同時捌くこと

はできない

Page 31: イベント駆動プログラミングとI/O多重化

なぜ 1プロセス 1スレッドで捌く必要があるの

か?

Page 32: イベント駆動プログラミングとI/O多重化

The C10K Problemでググれ

Page 33: イベント駆動プログラミングとI/O多重化

I/O多重化の仕組み

Page 34: イベント駆動プログラミングとI/O多重化

I/Oイベント待ち

I/Oイベント処理

後処理

I/Oイベント登録

Page 35: イベント駆動プログラミングとI/O多重化

非同期 echoサーバを題材にサンプルコードで見

Page 36: イベント駆動プログラミングとI/O多重化

多重化してない例

Page 37: イベント駆動プログラミングとI/O多重化

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); }}

Page 38: イベント駆動プログラミングとI/O多重化

多重化での処理の流れ

Page 39: イベント駆動プログラミングとI/O多重化

サーバ

クライアント

待ち受けソケット(イベント監視対象につっこむ)

Page 40: イベント駆動プログラミングとI/O多重化

サーバ

クライアント

待ち受けソケット(イベント監視対象)

Page 41: イベント駆動プログラミングとI/O多重化

サーバ

クライアント

待ち受けソケット(イベント監視対象)

接続ソケット(イベント監視対象につっこむ)

accept(sock)

Page 42: イベント駆動プログラミングとI/O多重化

サーバ

クライアント

待ち受けソケット(イベント監視対象)

接続ソケット(イベント監視対

象)

Page 43: イベント駆動プログラミングとI/O多重化

selectによる多重化

Page 44: イベント駆動プログラミングとI/O多重化

https://gist.github.com/mizzy/5343931

Page 45: イベント駆動プログラミングとI/O多重化

epollによる多重化

Page 46: イベント駆動プログラミングとI/O多重化

https://gist.github.com/mizzy/5343937

Page 47: イベント駆動プログラミングとI/O多重化

多重化用関数

Page 48: イベント駆動プログラミングとI/O多重化

selectpoll

epollkqueue

/dev/poll

Page 49: イベント駆動プログラミングとI/O多重化

select/pollは全部のソケットを調べる

Page 50: イベント駆動プログラミングとI/O多重化

epoll, kqueue, /dev/pollはイベントが発生したソケットだけを調べることができる

Page 51: イベント駆動プログラミングとI/O多重化

イベントライブラリ

Page 52: イベント駆動プログラミングとI/O多重化

libeventlibev

Page 53: イベント駆動プログラミングとI/O多重化

OSによる違いを吸収してくれる

Page 54: イベント駆動プログラミングとI/O多重化

I/O多重化以外にもタイマーイベントやシグナルイベントなんかも扱える

Page 55: イベント駆動プログラミングとI/O多重化

node.jsはlibevent + libeio

Page 56: イベント駆動プログラミングとI/O多重化

各種言語による非同期 echoサーバ

Page 57: イベント駆動プログラミングとI/O多重化

Perl(AnyEvent)

Page 58: イベント駆動プログラミングとI/O多重化

https://gist.github.com/mizzy/5343944

Page 59: イベント駆動プログラミングとI/O多重化

Ruby(EventMachine)

Page 60: イベント駆動プログラミングとI/O多重化

https://gist.github.com/mizzy/5343953

Page 61: イベント駆動プログラミングとI/O多重化

Python(twisted)

Page 62: イベント駆動プログラミングとI/O多重化

https://gist.github.com/mizzy/5343956

Page 63: イベント駆動プログラミングとI/O多重化

Python(eventlet)

Page 64: イベント駆動プログラミングとI/O多重化

https://gist.github.com/mizzy/5343959

Page 65: イベント駆動プログラミングとI/O多重化

node.js

Page 66: イベント駆動プログラミングとI/O多重化

https://gist.github.com/mizzy/5343964

Page 67: イベント駆動プログラミングとI/O多重化

イベント駆動プログラミングのデメリット

Page 68: イベント駆動プログラミングとI/O多重化

マルチコアでスケールしない

Page 69: イベント駆動プログラミングとI/O多重化

処理の流れが追いにくい書きにくい

Page 70: イベント駆動プログラミングとI/O多重化

var req_to_zenrin = http.request( options, function(res2) { res2.on('end', function() { res.end(); }); res2.on('data', function(chunk) { res.write(chunk); }); });

Page 71: イベント駆動プログラミングとI/O多重化

var referer;sdb.getItem( 'gha', host, function( error, result ) { if ( result ) { referer = ‘http://hoge.com/’; } });

// sdb.getItem()終了前に次の処理

Page 72: イベント駆動プログラミングとI/O多重化

sdb.getItem( 'gha', host, function( error, result ) { if ( result ) { access_to_zenrin('http://hoge.com'); } else { access_to_zenrin(); } });

Page 73: イベント駆動プログラミングとI/O多重化

ネットワークアクセスを伴う

処理をすべて非同期で書かないといけない

Page 74: イベント駆動プログラミングとI/O多重化

なので libmysqlclientは使えない

Page 75: イベント駆動プログラミングとI/O多重化

node-mysqlは libmysqlclient相当の処理を再実装してる

(っぽい)

Page 76: イベント駆動プログラミングとI/O多重化

参考文献

Page 77: イベント駆動プログラミングとI/O多重化
Page 78: イベント駆動プログラミングとI/O多重化