Python 비동기: 태스크 집합 대기하기

비동기 작업의 완료를 기다리기 위해 Python의 asyncio.wait() 함수를 사용할 수 있습니다. 이 함수는 다양한 조건에 따라 실행될 수 있습니다. 예를 들어 모든 태스크가 완료되거나, 첫 번째 태스크가 완료되었을 때, 또는 첫 번째 태스크가 예외로 실패했을 때까지 기다릴 수 있습니다.

아래에서는 이를 더 자세히 살펴보겠습니다.

1. asyncio.wait()란?

asyncio.wait() 함수는 여러 비동기 작업이 완료될 때까지 기다리는 데 사용됩니다. 이 함수는 주어진 조건에 따라 태스크 집합을 관리하며, 해당 조건이 충족되면 제어를 반환합니다. 기본적으로 모든 태스크가 완료될 때까지 기다립니다.

이 함수는 두 개의 세트를 포함하는 튜플을 반환합니다. 첫 번째 세트는 "완료된" 작업을, 두 번째 세트는 "대기 중인" 작업을 포함합니다.

2. asyncio.wait() 사용 방법

asyncio.wait() 함수는 일반적으로 Task 객체의 컬렉션을 인수로 받습니다. 아래 코드는 10개의 태스크를 생성하는 예제입니다.

# 여러 태스크 생성
tasks = [asyncio.create_task(work_coroutine(i)) for i in range(10)]

asyncio.wait() 함수는 특정 조건이 만족되기 전까지 실행을 차단합니다. 기본적으로 모든 태스크가 완료될 때까지 기다립니다.

모든 태스크 완료를 기다림

completed, pending = await asyncio.wait(tasks)

기술적으로 asyncio.wait()는 코루틴을 반환하는 코루틴 함수입니다. 따라서 이를 명시적으로 대기할 수도 있습니다.

wait 코루틴 생성

wait_coroutine = asyncio.wait(tasks)

코루틴 대기

result_tuple = await wait_coroutine

또한 return_when 매개변수를 통해 대기 조건을 지정할 수 있습니다. 예를 들어, 첫 번째 태스크가 완료되었을 때 기다림을 종료하려면 다음과 같이 설정합니다.

첫 번째 태스크 완료 시점에서 기다림 종료

completed, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)

첫 번째 예외 발생 시 기다림을 종료하려면 다음을 사용합니다.

첫 번째 예외 발생 시점에서 기다림 종료

completed, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)

타임아웃 값을 설정하여 특정 시간 동안만 기다릴 수도 있습니다.

타임아웃 설정 (3초)

completed, pending = await asyncio.wait(tasks, timeout=3)

타임아웃이 발생하면 완료된 작업의 부분 집합과 아직 완료되지 않은 작업들이 반환됩니다.

3. 모든 태스크 완료 대기 예제

아래는 asyncio.wait()를 사용하여 모든 태스크가 완료될 때까지 기다리는 간단한 예제입니다.

# Python 비동기 예제: 모든 작업 완료 대기
import random
import asyncio

# 새로운 태스크에서 실행될 코루틴
async def work_coroutine(index):
# 0부터 1 사이의 임의 값 생성
delay = random.uniform(0.5, 1.5)
# 일정 시간 동안 대기
await asyncio.sleep(delay)
# 결과 출력
print(f"> 작업 {index} 완료 ({delay:.2f}초)")

# 메인 코루틴
async def main():
# 여러 태스크 생성
tasks = [asyncio.create_task(work_coroutine(i)) for i in range(5)]
# 모든 태스크 완료 대기
done, pending = await asyncio.wait(tasks)
# 최종 결과 출력
print("모든 작업 완료")

# 프로그램 실행
asyncio.run(main())

위 코드는 먼저 5개의 태스크를 생성하고 각각 임의의 시간 동안 대기한 후 완료됩니다. 모든 작업이 완료되면 "모든 작업 완료"라는 메시지를 출력합니다.

예상 출력:

> 작업 3 완료 (0.67초)
> 작업 1 완료 (0.84초)
> 작업 2 완료 (1.12초)
> 작업 4 완료 (1.33초)
> 작업 0 완료 (1.49초)
모든 작업 완료

각 실행마다 결과는 다를 수 있습니다.

태그: asyncio coroutine asynchronous-programming

7월 23일 07:57에 게시됨