以下は、2つのバックグラウンドタスクを実行する単純なasyncioループです。asyncio.wait_for()にタイムアウトが必要なのはなぜですか?
これらは両方とも単純なカウントを実行します。最初のものは永遠にカウントされ、 try/exceptで囲まれています。 2番目は5までカウントし、最初の1つをキャンセルし、 はループを停止します。
キャンセルが完了していることを確実にすることの2つの方法があります -
asyncio.wait([a sequence of futures])
asyncio.wait_for(a single future)
どちらのオプションのタイムアウトを取るが。
タイムアウトなしで最初の方法を使用すると、キャンセルが完了し、 ループが停止します。
タイムアウトなしで2番目の方法を使用すると、将来はキャンセルされますが、 プログラムがハングします。
タイムアウトを2番目のタイムアウトに追加すると、最初のタイムアウトと同じ動作をします。
これには理由がありますか?
私はバージョン3.6.0を使用しています。
import asyncio
from itertools import count
async def counter1():
cnt = count(1)
try:
while True:
print('From 1:', next(cnt))
await asyncio.sleep(1)
except asyncio.CancelledError:
print('counter1 cancelled')
async def counter2():
cnt = count(1)
for i in range(5):
print('From 2:', next(cnt))
await asyncio.sleep(1)
cnt1.cancel()
# await asyncio.wait([cnt1]) # works
# await asyncio.wait_for(cnt1) # hangs
await asyncio.wait_for(cnt1, 1) # works
loop.stop()
loop = asyncio.get_event_loop()
cnt1 = asyncio.ensure_future(counter1())
cnt2 = asyncio.ensure_future(counter2())
loop.run_forever()
私は答えの半分を考え出しました。 'timeout'はwait()を使うときはオプションの引数ですが、wait_for()を使うときは必要な引数です。したがって、asyncioは例外を発生させています。しかし、なぜ私はトレースバックが現れないのか分かりません。 –