파이썬의 asyncio 모듈을 사용하여 동기(Synchronous)와 비동기(Asynchronous) 방식의 차이점을 알아보고 실무적인 사용법을 정리합니다.

파이썬 3.5부터 async와 await 키워드가 공식 도입되어 비동기 프로그래밍을 지원합니다.
import asyncio
import time
# async def로 선언하면 코루틴 객체를 리턴하는 함수가 됩니다.
async def hello():
print('hello python!')
# 일반적인 호출 방식으로는 실행되지 않습니다.
# await hello() 또는 asyncio.run(hello())를 사용해야 합니다.
동기 방식에서는 모든 작업 시간이 합산되어 나타납니다.
def sync_work(icon, seconds=0):
print(f'{icon} {seconds}초 작업 시작')
start = time.time()
time.sleep(seconds) # 작업이 끝날 때까지 여기서 멈춤
end = time.time()
print(f"{icon} 작업종료: {end-start:.3f}초 소요")
def sync_all():
sync_work('🍆', 3)
sync_work('🍊', 1)
sync_work('🥦', 2)
start = time.time()
sync_all()
end = time.time()
print(f'>>> 총 경과시간: {end - start:.3f}초')
# 결과: 약 6초 (3+1+2)
비동기 방식에서는 대기 시간 동안 다른 작업을 수행하므로, 가장 오래 걸리는 작업 시간을 기준으로 전체 작업이 완료됩니다.
async def async_work(icon, seconds=0):
print(f'{icon} {seconds}초 작업 시작')
start = time.time()
await asyncio.sleep(seconds) # 대기하는 동안 제어권을 넘김
end = time.time()
print(f'{icon} 작업종료: {end - start:.3f}초 소요')
return f'{icon}-{seconds}작업'
async def async_all():
# Task를 생성하여 비동기 실행을 예약합니다.
task1 = asyncio.create_task(async_work('🍆', 3))
task2 = asyncio.create_task(async_work('🍊', 1))
task3 = asyncio.create_task(async_work('🥦', 2))
# gather를 통해 여러 비동기 작업을 동시에 기다리고 결과값을 모읍니다.
result = await asyncio.gather(task1, task2, task3)
return result
start = time.time()
# 주피터/코랩 환경이 아닐 경우 asyncio.run(async_all()) 사용
result = await async_all()
end = time.time()
print(f'>>> 총 경과시간: {end - start:.3f}초')
print(f'결과 리스트: {result}')
# 결과: 약 3초 (가장 긴 작업인 3초에 수렴)
asyncio는 성능 향상의 필수 요소입니다.