今さらPython3 (73) - 並行処理のつづき

第11章の並列処理のつづき。

入門 Python 3

入門 Python 3

遅い部分はスレッドなり、プロセスなりに外出しするというのが前回の話だけど、それ以外にもイベント駆動方法があるらしい。

gevent

とりあえずpip3でgeventをインストールしようとしたら、release1.0.2を見つけてきてインストールしようとするがエラー。本には、まだPython3に対応しきれていないと書いてあったので、本と同じようにpython2.7で試そうと同じくpipでやってもエラー。ということで、最新の情報を調べると、2015年12月11日に出た1.1rc2というのがあるらしい。Release candidateで正式版ではないが、動作を試すぐらいの目的なら大丈夫だろうということで試す。

pypi.python.org

ローカルにファイルを保存した上で、こうやってインストールしてみたら行けた。

$ pip3 install gevent-1.1rc2-cp34-cp34m-macosx_10_6_intel.whl
Processing ./gevent-1.1rc2-cp34-cp34m-macosx_10_6_intel.whl
Requirement already satisfied (use --upgrade to upgrade): greenlet>=0.4.9 in /Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages (from gevent==1.1rc2)
Installing collected packages: gevent
Successfully installed gevent-1.1rc2

こんなコードを作って動かしてみる。ちなみに、本に書いてあるソースの3つめのサイトにアクセスしようとしたら、変なサイトに転送されたので別の似たようなサイトに差し替えてある。

出てきた結果はこれ。

$ python3 gevent_test.py
66.6.44.4
64.233.189.121
103.28.248.76

gevent.spawn()は、グリーンレット(greenlet)というスレッド的なモノを作るという意味。spawnって卵を産むとか大量に作り出すみたいな意味らしいので、意味が分かればなるほどって感じ。gevent.socket.gethostbynameが非同期に実行されるということは、それぞれの卵に対して、「おまえ、これやっとけ」と指示を出して、次に移るので並列と同じような効果があると考えれば良いのかな。最後にgevent.joinall()でジョブの終了を待って返り値を出力するという流れになると。

今度は、モンキーパッチング関数を使うパターン。

from event import monkey
monkey.patch_socket()

とやると、Pythonコードで書かれた標準モジュールがグリーンレットを使うように書き換える。さらに多くの標準ライブラリがモンキーパッチングされるには、下みたいにmonkey.patch_all()を使うと良いらしい。


$ gevent_monkey.py
66.6.44.4
64.233.189.121
103.28.248.76

モンキーパッチングしても、それぞれ実行されるコードの処理が遅くては、あまり効果は得られない。ま、当たり前かな。

gevent以外にもイベント駆動フレームワークで利用されているのはこれらとのこと。
Tornado Web Server — Tornado 4.3 documentation
Gunicorn - Python WSGI HTTP Server for UNIX

twisted

twistedも今の段階では、Ready for Python3ではないみたい。このリンクにあるグラフが一番分かりやすくて、赤い部分がまだ未対応とのこと。

https://rawgit.com/mythmon/twisted-py3-graph/master/index.html

とは言え、一応この本に書いてあることのほとんどを試すことを前提に進めているので、Python2.7を使って見ようということで、インストールしてみる。

pip install twisted
Requirement already satisfied (use --upgrade to upgrade): twisted in /Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages
Requirement already satisfied (use --upgrade to upgrade): zope.interface>=4.0.2 in /Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages (from twisted)
Requirement already satisfied (use --upgrade to upgrade): setuptools in /Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages (from zope.interface>=4.0.2->twisted)

今使っている環境では、Python2.7が先に入っていたので、pipとコールするとPython2.7用、pip3とコールするとPython3.4用になる。すでにインストール済だったらしい。


Client: Knock, knock
Server: Who's there?
Client: Disappearing client
Server: Disappearing client who?

サーバ側が何かを受信したときに、その内容に応じて値を返すようなイベントを起こしているという理解。