66

次のコードがあります。

@asyncio.coroutine
def do_something_periodically():
    while True:
        asyncio.async(my_expensive_operation())
        yield from asyncio.sleep(my_interval)
        if shutdown_flag_is_set:
            print("Shutting down")
            break

完了するまでこの関数を実行します。この問題は、シャットダウンが設定されている場合に発生します。関数は完了し、保留中のタスクは実行されません。

これはエラーです:

task: <Task pending coro=<report() running at script.py:33> wait_for=<Future pending cb=[Task._wakeup()]>>

シャットダウンを正しくスケジュールするにはどうすればよいですか?

コンテキストを示すために、5 秒ごとに /proc/stat から読み取り、その期間の CPU 使用率を計算し、結果をサーバーに送信するシステム モニターを作成しています。sigterm を受け取るまでこれらの監視ジョブをスケジュールし続けたいと思います。スケジュールを停止したら、現在のすべてのジョブが終了するのを待って、正常に終了します。

4

7 に答える 7

65

未完了のタスクを取得し、完了するまでループを再度実行してから、ループを閉じるか、プログラムを終了できます。

pending = asyncio.all_tasks()
loop.run_until_complete(asyncio.gather(*pending))
  • pending保留中のタスクのリストです。
  • asyncio.gather()一度に複数のタスクを待機できます。

すべてのタスクをコルーチン内で確実に完了させたい場合 (おそらく「メイン」コルーチンがある場合)、次のように実行できます。たとえば、次のようにします。

async def do_something_periodically():
    while True:
        asyncio.create_task(my_expensive_operation())
        await asyncio.sleep(my_interval)
        if shutdown_flag_is_set:
            print("Shutting down")
            break

    await asyncio.gather(*asyncio.all_tasks())

また、この場合、すべてのタスクが同じコルーチンで作成されるため、既にタスクにアクセスできます。

async def do_something_periodically():
    tasks = []
    while True:
        tasks.append(asyncio.create_task(my_expensive_operation()))
        await asyncio.sleep(my_interval)
        if shutdown_flag_is_set:
            print("Shutting down")
            break

    await asyncio.gather(*tasks)
于 2015-01-12T21:12:54.253 に答える