본문 바로가기

computer science

동기와 비동기

이번 장에서는 동기와 비동기 코드 처리 방법에 대해서 이해합니다.

 

 

동기 함수: 작성된 순서대로 동작한다. 

비동기 함수: 코드가 반드시 작성된 순서대로 동작하는 것이 아니다. (코루틴 함수라고도 한다.)

 

 

위의 차이를 아래의 실제 상황에 비유하여 설명하자면, 

 

ex) 자장면을 배달하는 배달부

delivery_func:

    1. 자장면을 주문자에게 배달한다.
    2. 해당 주문자가 다 먹은 그릇을 문 앞에 두면 수거한다.

 

만약에 주문자가 3명 (A, B, C)라고 한다. 

현재 상황 : A, B, C가 주문이 접수되고 배달부는 A, B, C의 자장면을 음식점에서 받은 상황이라고 하자.

 

 

동기의 경우, 

1. A의 자장면을 배달한다.

2. (20분 후) A의 자장면 그릇을 수거한다.

3. B의 자장면을 배달한다.

4. (20분 후) B의 자장면 그릇을 수거한다.

5. C의 자장면을 배달한다.

6. (20분 후) C의 자장면 그릇을 수거한다. 

 

코드로 실현하면,

import time

def delivery(name, mealtime):
    print(f"{name}에게 배달 완료!")
    time.sleep(mealtime)
    print(f"{name} 식사 완료, {mealtime}시간 소요...")
    print(f"{name} 그릇 수거 완료")

def main():
    delivery("A", 3)
    delivery("B", 3)
    delivery("C", 4)

if __name__ == "__main__":
    start = time.time()
    main()
    end = time.time()
    print(end - start)

 

결과 >

A에게 배달 완료!

A 식사 완료, 3시간 소요...
A 그릇 수거 완료
B에게 배달 완료!
B 식사 완료, 3시간 소요...
B 그릇 수거 완료
C에게 배달 완료!
C 식사 완료, 4시간 소요...
C 그릇 수거 완료
10.011337041854858

 

 

 

 

비동기의 경우,

1. A의 자장면을 배달한다.

2. B의 자장면을 배달한다.

3. C의 자장면을 배달한다

4. (20분 후) A의 자장면 그릇을 수거한다.

5. B의 자장면 그릇을 수거한다.

6. C의 자장면 그릇을 수거한다.

 

코드로 실현하면,

import time
import asyncio


async def delivery(name, mealtime):
    print(f"{name}에게 배달 완료!")
    await asyncio.sleep(mealtime)
    print(f"{name} 식사 완료, {mealtime}시간 소요...")
    print(f"{name} 그릇 수거 완료")

async def main():
    await asyncio.gather(
        delivery("A", 3),
        delivery("B", 3),
        delivery("C", 4),
    )

if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print(end - start)
결과 > 

A에게 배달 완료!
B에게 배달 완료!
C에게 배달 완료!
A 식사 완료, 3시간 소요...
A 그릇 수거 완료
B 식사 완료, 3시간 소요...
B 그릇 수거 완료
C 식사 완료, 4시간 소요...
C 그릇 수거 완료
4.002941131591797

 

오해하면 안되는 것이, 무조건 적으로 비동기 함수가 좋은 것은 아니다. 

상황에 따라서 비동기 함수가 때로는 느리게 작동할 때에도 있다. (경험담...)