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

minsing-jin·2024년 9월 11일
0

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]
  • 작업 완료 순서: Task 1, Task 3, Task 0, Task 4, Task 2 순서로 완료됐어. 이는 각 작업의 지연 시간이 다르기 때문이야.
  • 결과 순서: 하지만 asyncio.gather()결과를 입력된 순서대로 반환했어. 즉, results[0, 1, 2, 3, 4] 순서로 나왔어.

결론

  • 비동기 작업은 동시에 실행되지만, asyncio.gather()결과를 입력된 순서대로 반환해. 그래서 작업이 뒤죽박죽으로 완료되더라도, 결과는 항상 순서대로 나오는 거야.
  • 비동기 처리에서 작업이 완료되는 순서결과가 반환되는 순서는 다를 수 있지만, asyncio.gather()결과의 순서를 보장해줘.

추가 팁

만약 작업이 완료되는 순서대로 결과를 받고 싶다면, 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())

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

profile
why not? 정신으로 맨땅에 헤딩하고 있는 코린이

0개의 댓글