Pythonのasyncio
モジュールのイベントループが未処理タスクをどのように管理しているかについて質問があります。これは印刷されます実行Python asyncioタスクの注文
import asyncio
@asyncio.coroutine
def a():
for i in range(0, 3):
print('a.' + str(i))
yield
@asyncio.coroutine
def b():
for i in range(0, 3):
print('b.' + str(i))
yield
@asyncio.coroutine
def c():
for i in range(0, 3):
print('c.' + str(i))
yield
tasks = [
asyncio.Task(a()),
asyncio.Task(b()),
asyncio.Task(c()),
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([t1, t2, t3]))
:以下のコードを考えてみましょう、それは常に '' そしてその後、 'B' 'C' プリントアウトし
a.0
b.0
c.0
a.1
b.1
c.1
a.2
b.2
c.2
ていることに注意してください。私は、各コルーチンが何回繰り返されても、常にその順序で印刷されることになります。だから、これはイベントループがここでそれが次に実行するタスクを決定するために使用する内部キューを維持していることを私に伝え、Node.jsの背景から来る
b.100
c.100
a.100
ようなものを見ることはないと思います。最初にa()
をキューの先頭に置き、b()
、次にc()
とします。これは、リスト内のタスクの順番がasyncio.wait()
に渡されているためです。次に、yieldステートメントを実行するたびに、そのタスクがキューの最後に置かれます。より現実的な例では、非同期httpリクエストを行っている場合、http応答が戻った後にa()
をキューの最後に戻すと言います。
私はこれに助言を得ることができますか?
これは可能な限り早くコールバックを実行するため、I/Oが完了するのに異なる時間がかかると、順序が乱れるようになります。私の指摘は、(私の例のように)I/Oが起こっていなければ、舞台裏で起こっているタスク(おそらく待ち行列)の何らかの管理のために常に予測可能な順序で実行されるということでした。 OSスレッドスケジューラに従って実行されるスレッドのようなものとは対照的に、予測不能である。 – d512
I/Oがない場合は、asyncioを使用しないでください。それらは予測可能ではなく、さまざまな実装やバージョン、または異なる条件でどのように動作するかを確認することはできません。 – Udi
私は応答を感謝しますが、私の質問は 'asyncio'の適切な使い方ではなく、実装方法です。もちろん、ライブラリの実装の詳細については仮定を立てることは安全ではありません。この質問をすることによって、私はそうでないと示唆していませんでした。誰かがそれがどのように働いているか知っていたかどうかを知りたい – d512