2016-09-08 2 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()) 
관련 문제