SlideShare a Scribd company logo
イベント駆動プログラミン
       グと
    I/O多重化
イベント駆動プログラミング
イベントを待機し、起こっ
たイベントに従って処理を
行うプログラミングパラダ
     イム
フロー駆動型プログラミン
グと呼ばれる従来のプログ
ラミングパラダイムに対す
     る概念
GUIプログラミング
キーやマウスの入力をイベ
ントとして受け取って処理
ネットワークプログラミ
     ング
ネットワークI/Oを多重化して
1プロセス1スレッドで複数の
ネットワーク接続を同時に捌
       く
非イベント駆動な
ネットワークプログラミング
           process
Client       or
           thread


           process
Client       or
           thread


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

Client


           process
Client       or
           thread



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
多重化用関数
select
   poll
  epoll
 kqueue
/dev/poll
select/pollは全部の
ソケットを調べる
epoll, kqueue, /dev/pollはイ
ベントが発生したソケット
だけを調べることができる
イベントライブラリ
libevent
  libev
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
相当の処理を再実装してる
      (っぽい)
参考文献
イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化

More Related Content

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