python で同期的なコードの中で asyncio な処理を実行したい
twisted の reactor とは違って、 asyncio の event loop はスレッドごとに独立してるっぽい (get_event_loop()
で出てくるものが thread 毎に別っぽい) のと、
好きに新しく作ったり用が済んだら止めたりできるっぽい。
なので、同期的なコードの中で event loop を作成して、 その上で非同期なコードを実行して用が済んだら止める、 なんてことが簡単にできる。
ということの確認:
import asyncio from contextlib import contextmanager @contextmanager def with_loop(): # 新しく event loop を作成してセットして、 # 用が済んだら閉じる context manager loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) yield loop loop.close() asyncio.set_event_loop(None) def test(): # この関数自体は通常の同期的な処理 import aiohttp async def get(url): # aiohttp を使って非同期に HTTP request を投げ、 # response body を返す処理 response = await aiohttp.get(url) body = await response.read() return body with with_loop() as loop: # HTTP request を複数同時に投げるような例 tasks = [ get('http://localhost/'), get('http://localhost/'), ] # 作成した event loop を使って非同期処理を実行し、結果を受ける results = loop.run_until_complete(asyncio.gather(*tasks)) print(results) if __name__ == '__main__': import threading # test 関数は通常の関数なので、普通に thread を使って実行できる、 # ということの確認。 t1 = threading.Thread(target=test) t2 = threading.Thread(target=test) t1.start() t2.start() t1.join() t2.join()
動作はしているけど、 event loop を作って走らせて閉じてする負荷はどんなもんなんだろう?