[原]tornadoソースコード分析シリーズ(一)[tornado概要]

3111 ワード

引用:
tornadoはFacebookからオープンソースのサーバー「セット」です「pythonを作るのに適したウェブまたはそれ自体が提供する拡張可能な機能を使用して、不完全なwsgiプロトコルを完成し、迅速なウェブ開発に使用でき、epollの性能が優れている.本文は主にtornadoのネットワーク部分である非同期イベント処理と上層のIOstreamクラスが提供する非同期IOを分析し、他のモジュール、例えばウェブのtornado.web以降はゆっくりと分析を残す.
 
まず、いくつかの問題について説明します.
(1)文章はみんなが交流して使うために、もし間違いがあるならば、開源の精神を発揚して、共に交流します
(2)文章は説明しないが,いずれもLinux環境を例にとる.
(3)epollがある場合、tornadoはepollをデフォルトで使用します.ここではselectとKQueueは分析しません.
(4)効率的なC/C++ではなくpythonをネットワークライブラリとして使用する理由を聞かないでください.IO密集型プログラムでは、上位言語のプログラム実行の違いはそれほど大きくなく、tornadoで使用されているepoll部分もCで書かれているからです.
 
これから私たちのtornadoの旅を始めます.ソースコードを見る前に必ずソースコードが必要です.公式サイトにダウンロードしてください.
一.ソース組織:
  |---__init__.py
   ---auth.py
   ---......
   ---epoll.c
   ---ioloop.py
   ---iostream.py
   ---...
 
tornadoネットワーク部分の最も核心的な2つのモジュールはioloopである.pyとiostream.py、私たちが主に分析したのはこの2つの部分です.
  ioloop.pyは主に下層のepollあるいは他のIO多重化を非同期イベントとしてカプセル化して処理する
  iostream.pyは主に下層の非同期イベントのさらなるカプセル化であり,より上位のbuffer(IO)イベントをカプセル化する.
 
良い点はtornadoのソースコードの中で、すべて1つの簡単なDemoを提供して、私はこれらのDemoを例にとって、更に多くの話はコードを見るほうがよくて、プログラム猿の最も良い交流方式はコードを見ることです.
  
        import errno
        import functools
        import ioloop
        import socket

        def connection_ready(sock, fd, events):
            while True:
                try:
                    connection, address = sock.accept()
                except socket.error, e:
                    if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
                        raise
                    return
                connection.setblocking(0)
                handle_connection(connection, address)

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.setblocking(0)
        sock.bind(("", port))
        sock.listen(128)

#    ioloop   
        io_loop = ioloop.IOLoop.instance()
#   connection_ready         sock ,  socket     
        callback = functools.partial(connection_ready, sock)
#    ,          sock          ,        ,                
        io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
#  ~
        io_loop.start()

注釈の前に従来のサーバの作成方法が使用されていることがわかりますが、あまり紹介する必要はありません.ソケットインタフェースを非ブロックに設定することに注意してください.
ioloopインスタンスを作成します.ここではioloopを使用します.IOLoopでのinstance()スタティックメソッドを@classmethodでパッケージ
後ろのadd_handlerでは、リスナーインタフェースにコールバック関数とイベントタイプを登録しています.
動作は、対応するイベントタイプとコールバック関数が登録された後、プログラムが起動し始め、対応するスイートインタフェースにイベントが発生した場合(登録されたイベントタイプ)に対応するコールバック関数が呼び出されます.
コードがわかりやすい
リスニングスリーブインタフェースに読み取り可能なイベントが発生すると、新しい接続が来たことを意味し、コールバック関数でこのスリーブインタフェースacceptを呼び出し、対応する処理関数を呼び出すことができますが、実際には処理関数も非同期に設定されているはずです.対応する接続スリーブインタフェースもイベントループに追加し、対応するコールバック関数を登録することができますが、ここでは示されていません.
非ブロック方式のacceptを使用するとEAGAIN,EWOULDBLOCKエラーがしばしば返され,ここではこの接続を放棄する方式をとる.
 
まとめ:このような方法でソース分析を始めてとても水だと思って、最初の文章は短い精鋭を起点にして、広交の志を同じくする人です.