Pythonで非同期IOを利用する上での asyncio 基礎です。 コードはこちら https://github.com/jrfk/talk/tree/main/stpy
こわくないasyncio基礎と⾮同期IOJunya FukudaΈΜͳͷPythonษڧձ #84動くコードを添えて
View Slide
•ా ൏ʢJunya Fukudaʣʢ@JunyaFffʣ•גࣜձࣾຊγεςϜٕݚʢJSLʣॴଐ ݝͷձࣾ•WebΤϯδχΞ•GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ•ʢ͓͠͝ͱͰʣόϦϡʔϒοΫε•ຊ͖ʹѪ͞ΕΔαʔϏεΛࢦͯ͠ʢݹຊങऔɾൢചʣΪʔΫϥϘಡॻձ•GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ
Python実践•20221݄ൃച ٕज़ධࣾ•Python 3 ΤϯδχΞೝఆ࣮ફࢼݧ ओڭࡐ•2ʹ͓͢͢Ίʂࣙॻతʹ͍ͬͯ͋͛ͯͩ͘͞ʂ• ҎԼͷষΛ୲͍ͯ͠·͢• Chapter2 ίʔσΟϯάن• Chapter5 ܕώϯτ• Chapter19 ฒߦॲཧɼฒྻॲཧ
Python実践•20221݄ൃച•Python 3 ΤϯδχΞೝఆ࣮ફࢼݧ ओڭࡐ•2ʹ͓͢͢Ίʂࣙॻతʹ͍ͬͯ͋͛ͯͩ͘͞ʂ• ҎԼͷষΛ୲͍ͯ͠·͢• Chapter2 ίʔσΟϯάن• Chapter5 ܕώϯτ• Chapter19 ฒߦॲཧɼฒྻॲཧຊϓϨθϯτ͋Γ·͢ʂʂʂ
Python Monthly Topics Web連載•ٕज़ධࣾ - gihyo.jp•ஶऀͷ༗ࢤͰ•ຖ݄Pythonʹؔ͢ΔτϐοΫΛ࿈ࡌ
みなさんPythonでWebやっていますか?✋
JetBrains 2021年の調査https://www.jetbrains.com/ja-jp/lp/devecosystem-2021/python/
JetBrains 2021年の調査https://www.jetbrains.com/ja-jp/lp/devecosystem-2021/python/ิɿ2020ͷ݁ՌFastAPIͳ͔ͬͨ
Pythonで⾮同期IOといえば?
asyncio
すべてはasync/awaitから始まった
>IUUQTflPSJNPOEEFWCMPHBSUJDMFTJOUSPEVDUJPOUPBTHJBTZODQZUIPOXFCすべてはasync/awaitから始まった
asyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦasyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.5 Ͱ async/await ߏจasyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه•Python 3.5 Ͱ async/await ߏจasyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه•Python 3.5 Ͱ async/await ߏจasyncioはこわくない•ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه•Python 3.5 Ͱ async/await ߏจasyncioはこわくない•ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ•γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه•Python 3.5 Ͱ async/await ߏจasyncioはこわくない•ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ•γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO•RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷॳظͷϦϑΝϨϯεత࣮ aioquic
asyncio めっちゃこわい
•͜Θ͔ͬͨasyncio めっちゃこわい
•͜Θ͔ͬͨ•Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣasyncio めっちゃこわい•2ͭͷग़ձ͍https://www.oreilly.com/library/view/using-asyncio-in/9781492075325/
•͜Θ͔ͬͨ•ίϧʔνϯා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ•Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣasyncio めっちゃこわい•2ͭͷग़ձ͍
•͜Θ͔ͬͨ•ίϧʔνϯා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ•Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣasyncio めっちゃこわい•2ͭͷग़ձ͍•τʔΫ3 ʰFastAPIͬͯԿऀͩΖ͏ʁʱ - ಃࢁ ྮ ͞Μ
•asyncio͜Θ͍ͳ͋…
•asyncio͜Θ͍ͳ͋…•asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ 👋
•asyncio͜Θ͍ͳ͋…•asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ 👋•τʔΫ̎ Django /τʔΫ̏FastAPI ϫΫϫΫʂ
本⽇のおしながき(話すこと)•PythonͰඇಉظIOΛར༻͢Δ্Ͱͷ asyncio جૅ
本⽇のおしながき(話すこと)•࣮ࡍʹಈ͘ίʔυΛݟͳ͕Βʂʢ؆୯ͳϥΠϒίʔσΟϯά͠·͢ʣ•PythonͰඇಉظIOΛར༻͢Δ্Ͱͷ asyncio جૅ
本⽇のおしながき(話すこと)•࣮ࡍʹಈ͘ίʔυΛݟͳ͕Βʂʢ؆୯ͳϥΠϒίʔσΟϯά͠·͢ʣ•PythonͰඇಉظIOΛར༻͢Δ্Ͱͷ asyncio جૅ•GitHubʹίʔυ͋Γ·͢ʂ
本⽇のおしながき(話すこと)•࣮ࡍʹಈ͘ίʔυΛݟͳ͕Βʂʢ؆୯ͳϥΠϒίʔσΟϯά͠·͢ʣ•PythonͰඇಉظIOΛར༻͢Δ্Ͱͷ asyncio جૅ•GitHubʹίʔυ͋Γ·͢ʂ•Έͳ͞Μͥͻ͓खݩͰಈ͔͠ͳ͕Βʂ•https://github.com/jrfk/talk/tree/main/stpy
•asyncio ڊେ対象はアプリーケーション開発者向けのasyncio
•asyncio ڊେ•ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ対象はアプリーケーション開発者向けのasyncio
•asyncio ڊେ•Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ•ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ対象はアプリーケーション開発者向けのasyncio
•asyncio ڊେ•ϑϨʔϜϫʔΫϥΠϒϥϦ։ൃऀ͚ͷػೳͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏•Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ•ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ対象はアプリーケーション開発者向けのasyncio
•asyncio ڊେ•ϑϨʔϜϫʔΫϥΠϒϥϦ։ൃऀ͚ͷػೳͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏•Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ•ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ対象はアプリーケーション開発者向けのasyncio•ΞϓϦέʔγϣϯ։ൃऀ͚Λରʹͨ͠asyncio
•asyncio ڊେ•ϑϨʔϜϫʔΫϥΠϒϥϦ։ൃऀ͚ͷػೳͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏•Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ•ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ•ΞϓϦέʔγϣϯ։ൃऀ͚Λରʹͨ͠asyncio•લఏࣝͱͯ͠ݴ༿ͷઆ໌ͱɺasyncioͰΘͨͨͪ͠ʹͱͬͯඞཁͳ͜ͱ対象はアプリーケーション開発者向けのasyncio
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه•Python 3.5 Ͱ async/await ߏจasyncioはこわくない こわい•ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ•γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO•RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquic
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه•Python 3.5 Ͱ async/await ߏจasyncioはこわくない こわい•ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ•γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO•ઌRFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquic
⾔葉を完全に理解する
IUUQTEPDTQZUIPOPSHKBMJCSBSZBTZODJPIUNM
前提知識並⾏処理
前提知識並⾏処理並列処理
前提知識並⾏処理並列処理逐次処理
前提知識並⾏処理並列処理逐次処理タスクの処理
前提知識並⾏処理concurrent processing
前提知識並⾏処理concurrent processing複数の処理を同時に実⾏するという意味
前提知識並⾏処理concurrent processing複数の処理を同時に実⾏するという意味イメージ重視
前提知識並⾏処理ฒߦॲཧͱͦͷ۩ମతͳॲཧํࣜͷͭͰ͋ΔฒྻॲཧɺιϑτΣΞֶͷʹ͓͍ͯͬͱ෯͍τϐοΫͷͭͰ͢ɻेͷຊΛͬͯͯ͠ɺฒߦॲཧʹ͓͍ͯॏཁͳϙΠϯτฒߦॲཧϞσϧʹؔͯ͠ेͳٞͰ͖ͳ͍Ͱ͠ΐ͏ɻhttps://www.kadokawa.co.jp/product/302105001236/ΤΩεύʔτ1ZUIPOϓϩάϥϛϯάվగ൛ൃച
前提知識並⾏処理https://www.oreilly.co.jp/books/9784873119595/並⾏コンピューティング技法――実践マルチコア/マルチスレッドプログラミング並⾏プログラミング⼊⾨――Rust、C、アセンブリによる実装からのアプローチhttps://www.oreilly.co.jp/books/9784873114354/
イメージ重視
並⾏処理並列処理逐次処理
並⾏処理並列処理通常の関数を呼び出していく処理逐次処理
並⾏処理並列処理通常の関数を呼び出していく処理multiprocessingモジュール逐次処理
並⾏処理並列処理通常の関数を呼び出していく処理multiprocessingモジュールthreadingモジュール asyncioモジュール逐次処理
ちょっとわかりにくいのでレストラン🍽に例えます
レストラン
レストランどんなタスクがあるでしょうか
注⽂をとる
料理を作る注⽂をとる
料理を作る注⽂をとる 料理を運ぶ
逐次処理
注⽂を取る - 料理を作る - 料理を運ぶ逐次処理
注⽂を取る - 料理を作る - 料理を運ぶ完了してから次のタスク逐次処理
並列処理
並列処理注⽂を取る料理を作る料理を運ぶ
並列処理注⽂を取る料理を作る料理を運ぶ複数のタスクを同時に着⼿する
並⾏処理
並⾏処理注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ
並⾏処理注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶasyncioシングルスレッド
並⾏処理注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶasyncioシングルスレッド = ワンオペ
並⾏処理注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶasyncioシングルスレッド = ワンオペ同じ⼈
並⾏処理注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶasyncioシングルスレッド = ワンオペどのタイミングでタスクの切り替えをするのでしょうか 🤔
asyncioシングルスレッド = ワンオペどのタイミングでタスクの切り替えをするのでしょうか 🤔あなた
asyncioシングルスレッド = ワンオペどのタイミングでタスクの切り替えをするのでしょうか 🤔あなた お客様
asyncioシングルスレッド = ワンオペどのタイミングでタスクの切り替えをするのでしょうか 🤔あなた お客様←注⽂
asyncioシングルスレッド = ワンオペどのタイミングでタスクの切り替えをするのでしょうか 🤔あなた 考え中のお客様←注⽂待ち
asyncioシングルスレッド = ワンオペどのタイミングでタスクの切り替えをするのでしょうか 🤔あなた 考え中のお客様←注⽂待ちあなたから⾒て、外部のお客様、から注⽂という⼊⼒を待つ状態
asyncioどのタイミングでタスクの切り替えをするのでしょうか 🤔あなた 考え中のお客様←注⽂待ちあなたから⾒て、外部のお客様、から注⽂という⼊⼒を待つ状態
aどのタイミングでタスクの切り替えをするのでしょうか 🤔あなた 考え中のお客様←注⽂待ちあなたから⾒て、外部のお客様、から注⽂という⼊⼒を待つ状態⾮同期IOsyncio
a sync io
a sync io⼊⼒
a sync io同期 ⼊⼒
a sync ioしない 同期 ⼊⼒
asyncio⾮同期IO
asyncio⾮同期IOプログラムでいう外部の⼊⼒
asyncio⾮同期IOプログラムでいう外部の⼊⼒“ネットワークやデータベースへの⼊出⼒”
asyncio⾮同期IOプログラムでいう外部の⼊⼒“ネットワークやデータベースへの⼊出⼒”I/Oバウンドな処理
asyncio⾮同期IOプログラムでいう外部の⼊⼒“ネットワークやデータベースへの⼊出⼒”I/Oバウンドな処理 asyncioの得意なこと
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ•Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه•Python 3.5 Ͱ async/await ߏจasyncioはこわくない こわい•ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ•γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO•ઌRFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquicγϯάϧεϨουฒߦॲཧඇಉظ IO
ฒߦॲཧasyncioの周辺はちょっとこわくないγϯάϧεϨουඇಉظ IO
ฒߦॲཧasyncioの周辺はちょっとこわくないγϯάϧεϨουඇಉظ IOϫϯΦϖ
ฒߦॲཧasyncioの周辺はちょっとこわくないγϯάϧεϨουඇಉظ IOϫϯΦϖ外部のお客様、から注⽂という⼊⼒待ちの間に他のことをする
ฒߦॲཧasyncioの周辺はちょっとこわくないγϯάϧεϨουඇಉظ IOϫϯΦϖ外部のお客様、から注⽂という⼊⼒待ちの間に他のことをする得意なのはI/Oバウンド(ネットワークやDBの⼊出⼒)
asyncio🌷
asyncio で覚えておくことは3つasyncio
イベントループ
コルーチンイベントループ
コルーチンイベントループタスク
コルーチンイベントループタスク→ やること
コルーチンイベントループタスク→ やること→ やること+実⾏状態をもつ
コルーチンイベントループタスク→ やること→ やることを管理するもの→ やること+実⾏状態をもつ
注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶasyncio
注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶasyncioコルーチンやタスク
asyncio注⽂を取 注⽂を取 注⽂を取コ
asyncioイベントループ注⽂を取 注⽂を取 注⽂を取コ
asyncioイベントループ(あくまでイメージ)注⽂を取 注⽂を取 注⽂を取コ
考え中のお客様
考え中のお客様•จΛฉ͖ʹ͍͘•͓٬༷͕ΜͰɺɺจΛ͢Δ
asyncioは怖くない
•ා͘ͳ͍ϙΠϯτͦͷ̍asyncioは怖くない
•ා͘ͳ͍ϙΠϯτͦͷ̍asyncioは怖くない•async/await ͕͍͍ͭͯͯɺ௨ৗͷؔͷॲཧͱ͍͍ͩͨಉ͡
•ා͘ͳ͍ϙΠϯτͦͷ̍asyncioは怖くない•async/await ͕͍͍ͭͯͯɺ௨ৗͷؔͷॲཧͱ͍͍ͩͨಉ͡•·ͣஞ࣍ॲཧͰίʔυΛॻ͍ͯɺͦΕΛίϧʔνϯʹͯ͠Έ·͠ΐ͏
•ා͘ͳ͍ϙΠϯτͦͷ̍asyncioは怖くない•async/await ͕͍͍ͭͯͯɺ௨ৗͷؔͷॲཧͱ͍͍ͩͨಉ͡•·ͣஞ࣍ॲཧͰίʔυΛॻ͍ͯɺͦΕΛίϧʔνϯʹͯ͠Έ·͠ΐ͏•ίϧʔνϯͷϧʔϧ2ͭ
•ා͘ͳ͍ϙΠϯτͦͷ̍asyncioは怖くない•async/await ͕͍͍ͭͯͯɺ௨ৗͷؔͷॲཧͱ͍͍ͩͨಉ͡•·ͣஞ࣍ॲཧͰίʔυΛॻ͍ͯɺͦΕΛίϧʔνϯʹͯ͠Έ·͠ΐ͏•ؔͷఆٛʢdefʣͷલʹ async Λ͚ͭΔ•ίϧʔνϯͷϧʔϧ2ͭ
•ා͘ͳ͍ϙΠϯτͦͷ̍asyncioは怖くない•async/await ͕͍͍ͭͯͯɺ௨ৗͷؔͷॲཧͱ͍͍ͩͨಉ͡•·ͣஞ࣍ॲཧͰίʔυΛॻ͍ͯɺͦΕΛίϧʔνϯʹͯ͠Έ·͠ΐ͏•ؔͷఆٛʢdefʣͷલʹ async Λ͚ͭΔ•ίϧʔνϯΛݺͼग़͢߹ʹ await Λ͚ͭΔ•ίϧʔνϯͷϧʔϧ2ͭ
•ා͘ͳ͍ϙΠϯτͦͷ̍asyncioは怖くない•async/await ͕͍͍ͭͯͯɺ௨ৗͷؔͷॲཧͱ͍͍ͩͨಉ͡•·ͣஞ࣍ॲཧͰίʔυΛॻ͍ͯɺͦΕΛίϧʔνϯʹͯ͠Έ·͠ΐ͏•͓٬༷͕ΜͰɺɺจΛ͢Δ•จΛฉ͖ʹ͍͘•ཁ݅̎ͭ
では定義してみましょう
コルーチンわかったことίϧʔνϯͷఆٛasyncΛ͚ͭΔ͚ͩͨͩݺͼग़͚ͩ͢Ͱ݁ՌΛड͚औΕͳ͍
asyncioイベントループ注⽂を取 注⽂を取 注⽂を取コ(あくまでイメージ)
•C10Kͷճ•libuv(nodejs)ͷத֩Λͳ͢Έイベントループ
•C10Kͷճ•libuv(nodejs)ͷத֩Λͳ͢Έ•ίϧʔνϯλεΫΛεέδϡʔϦϯάイベントループ
•C10Kͷճ•libuv(nodejs)ͷத֩Λͳ͢Έ•ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷΈ•ίϧʔνϯλεΫΛεέδϡʔϦϯάイベントループ
•C10Kͷճ•libuv(nodejs)ͷத֩Λͳ͢Έ•ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷΈ•ͦ͜·Ͱҙࣝ͠ͳͯ͘ྑ͍ʢͦ͜ʹ͍Δ͜ͱͬͯͯʣ•ίϧʔνϯλεΫΛεέδϡʔϦϯάイベントループ
•C10Kͷճ•libuv(nodejs)ͷத֩Λͳ͢Έ•ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷΈ•ͦ͜·Ͱҙࣝ͠ͳͯ͘ྑ͍ʢͦ͜ʹ͍Δ͜ͱͬͯͯʣ•ίϧʔνϯλεΫΛεέδϡʔϦϯάイベントループ•asyncio ͷத֩Λͳ͢Έ
asyncio.run()を使ってみましょう•͓٬༷͕ΜͰɺɺจΛ͢Δ•จΛฉ͖ʹ͍͘•ཁ݅̎ͭ
コードを⾒⽐べてみましょう
コードのおさらい - 関数def order():print(“͝จʁ”)menu = long_thinking()print(menu)def long_thinking():print(“ͪΐͬͱͬͯͶ”)sleep(10000)return “͟Δͦ”order() # ࣮ߦ͢Δ
コードのおさらい - コルーチンasync def order():print(“͝จʁ”)menu = await long_thinking()print(menu)async def long_thinking():print(“ͪΐͬͱͬͯͶ”)await asyncio.sleep(10000)return “͟Δͦ”asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
イベントループasyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ•࣮͜ΕɺWebͰར༻͢Δ߹ʹॻ͘͜ͱ͕ͳ͍߹͋Δ
イベントループasyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ•࣮͜ΕɺWebͰར༻͢Δ߹ʹॻ͘͜ͱ͕ͳ͍߹͋Δ•ࠓग़ͯ͘ΔϑϨʔϜϫʔΫͰʢDjangoFastAPIʣASGIରԠ
イベントループasyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ•࣮͜ΕɺWebͰར༻͢Δ߹ʹॻ͘͜ͱ͕ͳ͍߹͋Δ•ࠓग़ͯ͘ΔϑϨʔϜϫʔΫͰʢDjangoFastAPIʣASGIରԠ•σϓϩΠUvicornͳͲͷαʔό͍·͢ΑͶ
イベントループasyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ•࣮͜ΕɺWebͰར༻͢Δ߹ʹॻ͘͜ͱ͕ͳ͍߹͋Δ•ࠓग़ͯ͘ΔϑϨʔϜϫʔΫͰʢDjangoFastAPIʣASGIରԠ$ uvicorn example:app•σϓϩΠUvicornͳͲͷαʔό͍·͢ΑͶ
イベントループasyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ•UvicornͳͲͷWebαʔό͕෦Ͱ࣮ߦͯ͘͠Ε͍ͯ·͢•ͨͩɺͦ͜ʹΠϕϯτϧʔϓ͕͍Δ͜ͱೝ͓͍ࣝͯͯ͠΄͍͠workers.py L82server.py L58
ここまでのまとめίϧʔνϯͷఆٛasyncΛ͚ͭΔ͚ͩ
ここまでのまとめίϧʔνϯͷఆٛasyncΛ͚ͭΔ͚ͩΠϕϯτϧʔϓͰ࣮ߦ͢Δඞཁ͕͋Δ
ここまでのまとめίϧʔνϯͷఆٛasyncΛ͚ͭΔ͚ͩΠϕϯτϧʔϓͰ࣮ߦ͢Δඞཁ͕͋Δasync/await͕͍͍ͭͯͯɺஞ࣍ॲཧͱجຊͷྲྀΕมΘΒͳ͍݁ՌΛͬͯɺ࣍ͷߦͷίʔυ͕࣮ߦ͞ΕΔ
次に並⾏処理にしてみましょう
考え中のお客様 3⼈とも
考え中のお客様 3⼈ともどうせ待つなら同時に聞いてしまいたい…
考え中のお客様 3⼈ともどうせ待つなら同時に聞いてしまいたい…•จΛฉ͖ʹ͍͘•͓٬༷͕ΜͰɺɺจΛ͢Δ
考え中のお客様 3⼈ともどうせ待つなら同時に聞いてしまいたい…•จΛฉ͖ʹ͍͘•͓٬༷͕ΜͰɺɺจΛ͢Δ•ಉ࣌ʹฉ͘
先ほどのコードをもとにお客様に3回聞いてみましょう
ここまでのまとめͨͩɺawait͢Δ͚ͩͰฒߦʹͳΒͳ͍
ここまでのまとめͨͩɺawait͢Δ͚ͩͰฒߦʹͳΒͳ͍1つのコルーチンが終わってから次のコルーチン普通の関数実⾏と同じ
•TaskΦϒδΣΫτタスク
•TaskΦϒδΣΫτ•ίϧʔνϯΛϥοϓ͠ɺ࣮ߦঢ়ଶΛͭタスク
•TaskΦϒδΣΫτ•ίϧʔνϯΛϥοϓ͠ɺ࣮ߦঢ়ଶΛͭ•Πϕϯτϧʔϓʹొ͢Δタスク
•TaskΦϒδΣΫτ•ίϧʔνϯΛϥοϓ͠ɺ࣮ߦঢ়ଶΛͭ•࡞Δํ๏Ͱɺ·֮ͣ͑Δͷ2ͭ•Πϕϯτϧʔϓʹొ͢Δタスク
•TaskΦϒδΣΫτ•ίϧʔνϯΛϥοϓ͠ɺ࣮ߦঢ়ଶΛͭ•࡞Δํ๏Ͱɺ·֮ͣ͑Δͷ2ͭ•Python3.7 ͰՃ͞Εͨ asyncio.create_task()•Πϕϯτϧʔϓʹొ͢Δ•ฒྻ࣮ߦΛॿ͚Δ asyncio.gather()タスク
タスクを作ってみましょう
ここまでのまとめタスクはただ作っただけでは実⾏されない
ここまでのまとめawait ͢Δඞཁ͕͋Δタスクはただ作っただけでは実⾏されない
ここまでのまとめawait ͢Δඞཁ͕͋Δタスクはただ作っただけでは実⾏されないawaitは中断と再開のキーとなる
ここまでのまとめawait ͢Δඞཁ͕͋Δタスクはただ作っただけでは実⾏されないawaitは中断と再開のキーとなるawaitΛΩʔʹΠϕϯτϧʔϓ͕λεΫΛΓସ͑ɺॲཧΛฒߦʹ͢Δʂgatherは便利
シンプルな asyncio のサンプルasync def long_thinking():print(“ͪΐͬͱͬͯͶ”)await asyncio.sleep(10000)return “͟Δͦ”
シンプルな asyncio のサンプルasync def long_thinking():print(“ͪΐͬͱͬͯͶ”)await asyncio.sleep(10000)return “͟Δͦ”asyncio.sleep(10000)
⾮同期IO - asyncioasyncio.sleep(10000)
⾮同期IO - asyncioasyncio.sleep(10000)外部⼊⼒を待つ状態
⾮同期IO - asyncioasyncio.sleep(10000)外部⼊⼒を待つ状態•I/Oόϯυ
⾮同期IO - asyncio•I/Oόϯυ•σʔλϕʔεͷଓ•WebAPIͷར༻ʹΑΔHTTPϦΫΤετ
考え中のお客様asyncio.sleep(10000)
考え中のお客様検索しないと決められないasyncio.sleep(10000)
考え中のお客様検索しないと決められないasyncio.sleep(10000) 3⼈とも
考え中のお客様検索しないと決められないasyncio.sleep(10000)HTTP通信 I/Oバウンド3⼈とも
考え中のお客様検索しないと決められないasyncio.sleep(10000)HTTP通信 I/Oバウンド3⼈ともrequests
外部I/Oのある処理を書いてみましょう
ここまでのまとめasyncioでHTTP通信をするにはrequestsではだめ
外部I/Oのある処理を書いてみましょうasyncio対応のライブラリで
ここまでのまとめasyncioでHTTP通信をするにはrequestsではだめasyncioରԠͷϥΠϒϥϦͰɺI/O͢Δඞཁ͕͋Δ
ίϧʔνϯasyncioはこわくないλεΫΠϕϯτϧʔϓ
ίϧʔνϯasyncioはこわくないλεΫΠϕϯτϧʔϓؔʹ async Λ͚ͭΔ͚ͩ ؊await
ίϧʔνϯasyncioはこわくないλεΫΠϕϯτϧʔϓΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ͓ͯ͘͠ͱྑ͖ʹܭΒͬͯΓସ͑ͯ͘ΕΔɻؔʹ async Λ͚ͭΔ͚ͩ ؊await
ίϧʔνϯasyncioはこわくないλεΫΠϕϯτϧʔϓΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ͓ͯ͘͠ͱྑ͖ʹܭΒͬͯΓସ͑ͯ͘ΕΔɻ登録してあるタスクをawaitのタイミングで切り替える。ただしasyncio対応が必要。ؔʹ async Λ͚ͭΔ͚ͩ ؊await
ίϧʔνϯasyncioはこわくないλεΫΠϕϯτϧʔϓcreate_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొgather(λεΫ ·ͨ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔasync defawait λεΫ ·ͨ ίϧʔνϯasynio.run(ίϧʔνϯ)
ίϧʔνϯasyncioはこわくないλεΫΠϕϯτϧʔϓcreate_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొgather(λεΫ ·ͨ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔasync defawait λεΫ ·ͨ ίϧʔνϯasynio.run(ίϧʔνϯ)まずはこれを抑えましょう
asyncioはこわくないΠϕϯτϧʔϓ loopΦϒδΣΫτ触れてないもの
asyncioはこわくないΠϕϯτϧʔϓ触れてないものfutureΦϒδΣΫτloopΦϒδΣΫτ
asyncioはこわくないΠϕϯτϧʔϓ触れてないものfutureΦϒδΣΫτloopΦϒδΣΫτެࣜυΩϡϝϯτɿϨϕϧAPIʹྨ
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτ
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃ
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃpython core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃPEP 492 -- Coroutines with async and await syntax ஶऀeuropython 2018 - Asyncio in Python 3 7 and 3 8
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃYury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯPEP 492 -- Coroutines with async and await syntax ஶऀ
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃYury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯPEP 492 -- Coroutines with async and await syntax ஶऀnormalϋʔυίΞ
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃpython core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃPEP 492 -- Coroutines with async and await syntax ஶऀeuropython 2018 - Asyncio in Python 3 7 and 3 8Python 3.10ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾʹloopΦϒδΣΫτͷࢦఆ͕ෆՄ
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃpython core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃPEP 492 -- Coroutines with async and await syntax ஶऀeuropython 2018 - Asyncio in Python 3 7 and 3 8Python 3.10ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾʹloopΦϒδΣΫτͷࢦఆ͕ෆՄloopΦϒδΣΫτfutureΦϒδΣΫτΛҙࣝͤͣʹasyncioར༻Մೳʹ
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃpython core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃPEP 492 -- Coroutines with async and await syntax ஶऀeuropython 2018 - Asyncio in Python 3 7 and 3 8Python 3.10ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾʹloopΦϒδΣΫτͷࢦఆ͕ෆՄloopΦϒδΣΫτfutureΦϒδΣΫτΛҙࣝͤͣʹasyncioར༻Մೳʹ Ξοϓσʔτ͕͍
asyncioはこわくない 緩やかな根拠Python 3.7 ͷΞοϓσʔτasyncio.create_task(), asyncio.gather(), asyncio.run() ͷՃpython core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃPEP 492 -- Coroutines with async and await syntax ஶऀeuropython 2018 - Asyncio in Python 3 7 and 3 8Python 3.10ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾʹloopΦϒδΣΫτͷࢦఆ͕ෆՄloopΦϒδΣΫτfutureΦϒδΣΫτΛҙࣝͤͣʹasyncioར༻Մೳʹ Ξοϓσʔτ͕͍༗༻ͳαϯϓϧίʔυաڈͷόʔδϣϯΛϕʔεʹ͍ͯ͠Δͷଟ͍
asyncioの話まとめ
まとめ•asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔コ
まとめ•asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔コ•3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ײతͰΘ͔Γ͘͢
まとめ•asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔コ•ਐԽͷૣ͍asyncio•3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ײతͰΘ͔Γ͘͢
まとめ•asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔コ•ਐԽͷૣ͍asyncio•3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ײతͰΘ͔Γ͘͢•࣮3.11Ͱࠓ͝հͨ͠༰͕Ұ෦Խͯ͠͠·͏͔ʁ
まとめ•asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔コ•ਐԽͷૣ͍asyncio•3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ײతͰΘ͔Γ͘͢•࣮3.11Ͱࠓ͝հͨ͠༰͕Ұ෦Խͯ͠͠·͏͔ʁ•PyConJP 2022 2022.10.14(Fri)-15(Sat) Ͱ͝հͰ͖Εʂͱࢥ͍·͢
まとめ•asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔コ•ਐԽͷૣ͍asyncio•3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ײతͰΘ͔Γ͘͢•࣮3.11Ͱࠓ͝հͨ͠༰͕Ұ෦Խͯ͠͠·͏͔ʁ•PyConJP 2022 2022.10.14(Fri)-15(Sat) Ͱ͝հͰ͖Εʂͱࢥ͍·͢•ͬͱasyncioଞͷʹ͍ͭͯΓ͍ͨʂ
まとめ•asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔コ•ਐԽͷૣ͍asyncio•3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ײతͰΘ͔Γ͘͢•࣮3.11Ͱࠓ͝հͨ͠༰͕Ұ෦Խͯ͠͠·͏͔ʁ•PyConJP 2022 2022.10.14(Fri)-15(Sat) Ͱ͝հͰ͖Εʂͱࢥ͍·͢•ͬͱasyncioଞͷʹ͍ͭͯΓ͍ͨʂ•͓͢͢Ίίϯςϯπͨ͘͞Μ͋Γ·͢ʂʢँࣙγʔτͰʣ
•ίϧʔνϯා͘ͳ͍ - Minimum Viable Programmerhttps://www.rhoboro.com/2019/02/09/coroutine-abstract.html•Using Asyncio in Python - Oreilly & Associates Inc謝辞•Yury Selivanov - Asyncio in Python 3 7 and 3 8https://www.youtube.com/watch?v=ReXxO_azV-w•asyncioͷTaskʹؔ͢Δجૅࣝhttps://aish.dev/python/20200711_asyncio_task.html•To many many internet articles, great books and member. 🙏
•࣮ͰΔasyncio -Πϕϯτϧʔϓͷਖ਼ମͱ Rei Suyama - PyCon JP 2021https://www.youtube.com/watch?v=O0Uwz2l_A_Q謝辞•Artisanal Async Adventures Jonas Obrist - PyCon APAC 2018https://www.youtube.com/watch?v=IbwirUn9ubA•To many many internet articles, great books and member. 🙏•async await ͷ͜͏ଆ Atsushi Odagiri - PyConKyushu 2022https://www.youtube.com/watch?v=ClSeOPoUH7c
ご静聴ありがとうございました 👋