본문으로 건너뛰기
Minsing Log
뒤로 가기

Async에서 결과가 순서대로 안나옴

Programming & CS

asycio 비동기처리에서 Idx가 왜 안 섞여나옴?

-> 비동기 처리의 결과가 뒤죽박죽 나오는것임!!

비동기 처리에서 작업이 순서대로 진행되는지 아니면 뒤죽박죽으로 진행되는지에 대한 질문을 이해했어. 비동기 처리의 특성상 작업이 동시에 실행될 수 있지만, 결과가 순서대로 나오는 이유는 asyncio.gather()의 동작 방식 때문이야. 이제 이 부분을 자세히 설명할게.

비동기 처리에서 순서가 유지되는 이유

  1. asyncio.gather()의 동작 방식:

    • asyncio.gather()는 여러 비동기 작업을 동시에 실행하지만, 결과는 입력된 순서대로 반환해. 즉, gather()에 전달된 작업들이 비동기적으로 실행되더라도, 결과 리스트는 작업을 전달한 순서대로 정렬돼.
    • 예를 들어, tasks = [task1, task2, task3]라는 작업 리스트가 있을 때, asyncio.gather(*tasks)는 각 작업이 비동기적으로 실행되더라도, 결과는 [result1, result2, result3]처럼 작업을 전달한 순서대로 반환돼.
  2. 비동기 작업의 실행 순서:

    • 비동기 작업은 동시에 실행될 수 있지만, 각 작업이 완료되는 시간은 다를 수 있어. 하지만 asyncio.gather()는 작업이 완료되는 순서와 상관없이 결과를 입력된 순서대로 반환해.
    • 예를 들어, task1이 3초, task2가 1초, task3이 2초 걸린다고 해도, asyncio.gather()는 결과를 [result1, result2, result3] 순서로 반환해. 즉, 작업이 완료되는 순서와 상관없이 결과는 항상 입력된 순서대로 나오는 거야.
  3. 비동기 작업의 병렬성:

    • 비동기 작업은 병렬적으로 실행되지만, 결과를 반환하는 방식은 asyncio.gather()가 순서를 보장해줘. 따라서 작업이 뒤죽박죽으로 실행되더라도, 결과는 항상 순서대로 나오는 거야.

예시 코드로 설명

import asyncio
import random

async def task(idx):
    delay = random.uniform(1, 3)  # 1초에서 3초 사이의 랜덤한 지연 시간
    await asyncio.sleep(delay)
    print(f"Task {idx} 완료 (지연 시간: {delay:.2f}초)")
    return idx

async def main():
    tasks = [task(i) for i in range(5)]
    results = await asyncio.gather(*tasks)
    print(f"결과: {results}")

# 이벤트 루프 실행
asyncio.run(main())

실행 결과 예시

Task 1 완료 (지연 시간: 1.23초)
Task 3 완료 (지연 시간: 1.45초)
Task 0 완료 (지연 시간: 2.12초)
Task 4 완료 (지연 시간: 2.34초)
Task 2 완료 (지연 시간: 2.89초)
결과: [0, 1, 2, 3, 4]

결론

추가 팁

만약 작업이 완료되는 순서대로 결과를 받고 싶다면, asyncio.gather() 대신 **asyncio.as_completed()**를 사용할 수 있어. as_completed()는 작업이 완료되는 순서대로 결과를 반환해.

import asyncio
import random

async def task(idx):
    delay = random.uniform(1, 3)
    await asyncio.sleep(delay)
    print(f"Task {idx} 완료 (지연 시간: {delay:.2f}초)")
    return idx

async def main():
    tasks = [task(i) for i in range(5)]
    for completed_task in asyncio.as_completed(tasks):
        result = await completed_task
        print(f"완료된 작업 결과: {result}")

# 이벤트 루프 실행
asyncio.run(main())

이 코드를 실행하면 작업이 완료되는 순서대로 결과가 출력될 거야.

공개 여정 구독

글이 올라오면 이메일로 보내드릴게요.

개발, 창업, 배움, 실패와 회고를 짧고 솔직하게 기록합니다. 검색으로 스쳐가는 독자가 아니라 여정을 따라오는 팬을 만들기 위한 뉴스레터입니다.

뉴스레터는 준비 중입니다. 그동안 RSS 로 구독하거나 이메일 로 알림을 요청해 주세요.


이 글 공유하기:

댓글

GitHub 계정으로 로그인해 댓글을 남길 수 있습니다.


이전 글
OpenAI Async 프로세싱 GOAT 설명
다음 글
비동기 처리의 작업 과정 원리