今さらPython3 (73) - 並行処理のつづき
第11章の並列処理のつづき。
- 作者: Bill Lubanovic,斎藤康毅,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/12/01
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
遅い部分はスレッドなり、プロセスなりに外出しするというのが前回の話だけど、それ以外にもイベント駆動方法があるらしい。
gevent
とりあえずpip3でgeventをインストールしようとしたら、release1.0.2を見つけてきてインストールしようとするがエラー。本には、まだPython3に対応しきれていないと書いてあったので、本と同じようにpython2.7で試そうと同じくpipでやってもエラー。ということで、最新の情報を調べると、2015年12月11日に出た1.1rc2というのがあるらしい。Release candidateで正式版ではないが、動作を試すぐらいの目的なら大丈夫だろうということで試す。
ローカルにファイルを保存した上で、こうやってインストールしてみたら行けた。
$ 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?
サーバ側が何かを受信したときに、その内容に応じて値を返すようなイベントを起こしているという理解。
asyncio
しばらくすると、これが標準なんだよという流れになると予想。
PEP 3156 -- Asynchronous IO Support Rebooted: the "asyncio" Module | Python.org
18.5. asyncio – 非同期 I/O、イベントループ、コルーチンおよびタスク — Python 3.4.3 ドキュメント
(つづく)