2016-09-08 7 views
2

asyncioを使用して、同時のネットワークI/Oを処理しようとしています。非常に多くの機能が単一ポイントでスケジュールされ、各ポイントが完了するまでに時間が大幅に異なります。受信したデータは、各出力に対して別々のプロセスで処理されます。将来のasyncioを待っています

データが処理される順序は関係ありません。したがって、出力待ちの可能性が非常に高いので、あらかじめ定義された順序ではなく、最後に何かが完了したらawaitにします。

def fetch(x): 
    sleep() 

async def main(): 
    futures = [loop.run_in_executor(None, fetch, x) for x in range(50)] 
    for f in futures: 
     await f 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main()) 

通常、先物がキューされた順番で待っていることは結構です:

Well behaved functions profiler graph

ブルー色は、各タスクはエグゼキュータのキューにある時間を表し、すなわちrun_in_executorが呼び出されていますが、機能はしました実行者は5つのタスクしか同時に実行しないため、まだ実行されていません。緑は関数自体の実行に費やされる時間です。赤は以前の先物すべてをawaitに待っていた時間です。機能が大幅に時間が異なる私の場合は

Volatile functions profiler graph

、私はローカルでGET出力を処理することができながら、待つためにキュー内の前の先物を待っているに失われた多くの時間があります。これにより、私のシステムはしばらくの間アイドル状態になり、いくつかの出力が同時に完了した後、さらに多くの要求が完了するのを待ってアイドル状態に戻ります。

await実行者にはどのような未来が完成するのですか?

+0

コルーチンの実行を視覚化するために使用したことはありますか? :) – PovilasB

+0

@PovilasB 'time.time()'とPIL – Mirac7

+0

のロギング多くの場合、先物を使用していると[as_completed](https://docs.python.org/3/library/concurrent.futures.html)が見つかりました#concurrent.futures.as_completed)イベントが終了すると、それを処理するのに非常に役立ちます。 –

答えて

3

asyncio.waitreturn_when=asyncio.FIRST_COMPLETEDを探しているようです。

def fetch(x): 
    sleep() 

async def main(): 
    futures = [loop.run_in_executor(None, fetch, x) for x in range(50)] 
    while futures: 
     done, futures = await asyncio.wait(futures, 
      loop=loop, return_when=asyncio.FIRST_COMPLETED) 
     for f in done: 
      await f 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main())