Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Pythonによる非同期プログラミング入門

33,756 views

Published on

Pythonによる非同期プログラミング入門

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Pythonによる非同期プログラミング入門

  1. 1. Pythonによる 非同期プログラミング入門 関根裕紀
  2. 2. 自己紹介 • 関根裕紀(せきね ひろのり) • アライドアーキテクツ株式会社 • ソフトウェア・エンジニア • Twitter(@checkpoint )
  3. 3. 経歴 • 前職まで • RSSリーダー、SNS、WebMail、写真共有サービスなど • 現在(アライドアーキテクツ) • Webアプリケーション開発全般を担当 • http://showcase.cool/ • 発表 • http://ll.jus.or.jp/2014/archives/slides
  4. 4. アジェンダ • 同期I/O、非同期I/O • Pythonの非同期フレームワーク • asyncio概要、サンプル
  5. 5. 同期I/O コンピュータ内部のCPUと周辺装置のデータ入出力(I/O)において、データの 送受信の完了を待ってから他の処理を開始する方式。 ! 同期I/Oでは、I/O処理が始まると他の処理はいったん停止し、送受信が完了 してから続きの処理を開始・継続する。これに対し、I/O処理と並列に、送受 信が完了していなくても可能な処理を進める方式を非同期I/O(ノンブロッキ ングI/O)という ! IT用語辞典 ( http://e-words.jp/w/E5908CE69C9FI2FO.html ) より
  6. 6. コーヒーショップ(同期版) • 注文する • 出来るのを待つ • 受け取る
  7. 7. 非同期I/O コンピュータ内部のCPUと周辺装置のデータ入出力(I/O)において、データの 送受信の完了を待たずに他の処理を開始する方式。並列処理の一種。 ! 非同期I/Oでは、I/O処理と並列に、データの送受信が完了していなくても可 能な処理を進め、送受信が済まないと進められない処理にたどりついた場合 に、そこで送受信の完了を待つ。これに対し、正常に送受信が完了したかど うかの結果を待ち、送受信処理に完了してから残りの処理を行う方式を同期I/ O(ブロッキングI/O)という。 IT用語辞典 ( http://e-words.jp/w/E5908CE69C9FI2FO.html ) より
  8. 8. コーヒーショップ(非同期版) • 注文する • 別の所で待つ • 準備が出来たら呼ばれて、受け取る
  9. 9. 比較 同期版 非同期版高速化
  10. 10. どういう場合に使う? • IOの待ち時間が長い処理 • コネクションの取得 • 外部サービスの呼び出し • APIの呼び出し • 逆にCPUバウンドなプログラムには有効ではない
  11. 11. Pythonの非同期処理の選択肢 • twisted • tornado • gevent • thread、multi process、and etc…
  12. 12. Twisted • イベント駆動型のネットワークプログラミングフ レームワーク • TCP、UDP、SSL/TSL、などのサポート • 多数のプロトコルに対応(HTTP、SSH、FTP) • Deferred(遅延評価オブジェクト) • 外部イベントループとの結合
  13. 13. Tornado • Facebook( FriendFeed )が開発 • オープンソース • Webフレームワーク + 非同期通信ライブラリ • 非常に高速(先日のLTでも発表があり) • 現在でもよく使われている
  14. 14. 選択肢が多い • 選択肢が多いのは素晴らしい • どれがスタンダードなのかわからない • APIのスタイルが違う • 結合しているイベントループの種類が違う
  15. 15. asyncio • PEP 3156 ( http://legacy.python.org/dev/peps/pep-3156/ ) • Python3.4から標準ライブラリ • 非同期i/oの共通のコンポーネントを提供 • Windows, Linuxをサポート • 既存のフレームワークを置き換えるのではなく、 補完する
  16. 16. アーキテクチャ • Event loop • Corutines • Future、Task
  17. 17. Event loop • プラットフォームに最適なIO処理を提供
  18. 18. イベントループの取得 • asyncio.get_event_loop() • asyncio.set_event_loop(loop) • asyncio.new_event_loop()
  19. 19. イベントループの実行、停止 • loop.run_forever() • loop.run_until_complete(future) • loop.is_running() • loop.stop() • loop.is_closed()
  20. 20. コールバック • loop.call_soon(callback,*args) • loop.call_later(delay, callback, *args) • loop.call_at(when, callback, *args) • loop.time()
  21. 21. ファイルディスクリプタ • loop.add_reader(fd, callback, *args) • loop.remove_reader(fd) • loop.add_writer(fd, callback, *args) • loop.remove_writer(fd)
  22. 22. UNIX シグナル • loop.add_signal_handler(signum, callback, *args) • loop.remove_signal_handler(sig)
  23. 23. 他にもたくさん • http://docs.python.jp/3/library/asyncio.html
  24. 24. Hello World import asyncio ! def print_and_repeat(loop): print('Hello World') loop.call_later(2, print_and_repeat, loop) ! loop = asyncio.get_event_loop() loop.call_soon(print_and_repeat, loop) loop.run_forever() http://docs.python.jp/3/library/asyncio-eventloop.html#example-hello-world-callback
  25. 25. Signal Sample import asyncio import functools import os import signal ! def ask_exit(signame): print("got signal %s: exit" % signame) loop.stop() ! loop = asyncio.get_event_loop() for signame in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, signame), functools.partial(ask_exit, signame)) ! print("Event loop running forever, press CTRL+c to interrupt.") print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid()) loop.run_forever() http://docs.python.jp/3/library/asyncio-eventloop.html#example-set-signal-handlers-for-sigint-and-sigterm
  26. 26. Coroutines • generator • @asyncio.coroutine • 任意の箇所で一旦処理を中止し、処理を再開
  27. 27. Coroutine Sample import asyncio ! @asyncio.coroutine def greet_every_two_seconds(): while True: print('Hello World') yield from asyncio.sleep(2) ! loop = asyncio.get_event_loop() loop.run_until_complete(greet_every_two_seconds()) http://docs.python.jp/3/library/asyncio-task.html#example-hello-world-coroutine
  28. 28. Chain Coroutines import asyncio ! @asyncio.coroutine def greet_every_two_seconds(): while True: print('Hello World') yield from asyncio.sleep(2) ! loop = asyncio.get_event_loop() loop.run_until_complete(greet_every_two_seconds()) http://docs.python.jp/3/library/asyncio-task.html
  29. 29. Future • 呼び出し可能オブジェクトの非同期実行をカプ セル化 • future.add_done_callback() => 登録 • future.result() => 結果の取得
  30. 30. 実際はどう使う? • aiohttp( https://github.com/KeepSafe/aiohttp )
  31. 31. aiohttp @asyncio.coroutine def request(method, url, *, params=None, data=None, headers=None, cookies=None, files=None, auth=None, allow_redirects=True, max_redirects=10, encoding='utf-8', version=aiohttp.HttpVersion11, compress=None, chunked=None, expect100=False, connector=None, loop=None, read_until_eof=True, request_class=None, response_class=None):
  32. 32. aiohttp response = yield from aiohttp.request('GET', 'http://python.org') body = yield from response.read() print(body)
  33. 33. まとめ • まずはEventloop、Coroutine、Futureを覚える • スレッドなどに比べて概念が難しい(個人的に) • 徐々にasyncioをベースにした実装が出てくるはず。
  34. 34. ご静聴ありがとうございました。

×