1. 요약
파이썬 코루틴(Coroutine)은 비동기 프로그래밍에서 자주 사용되는 기능으로, 함수가 중단되고 재개될 수 있는 방식으로 설계되었습니다. 코루틴을 사용하면 작업을 중단하거나 다시 시작할 수 있어, 효율적인 비동기 처리와 리소스 절약이 가능합니다. 특히, 데이터 파이프라인과 이벤트 기반 프로그래밍에서 유용하게 쓰이며, 파이썬 asyncio 모듈과 함께 비동기 I/O 작업을 효율적으로 처리하는 데 활용됩니다.
2. 개념
코루틴은 전통적인 함수와 달리 호출자와 양방향으로 데이터를 주고받을 수 있는 함수입니다. 단일 쓰래드를 사용하여 스택을 기반으로 비동기 작업을 수행시킵니다. 코루틴은 제너레이터(generator)와 유사하게 yield 를 사용하기도 하지만, 3.5버전 이후부터는 주로 await와 async 키워드를 사용합니다. 이를 통해 기존 상태를 저장하고, 메인과 서브간의 데이터를 양방향으로 전송함으로써 함수 실행을 중단하고 필요에 따라 재개하는 등의 코루틴 제어를 가능하게 합니다. 코루틴은 시간이 많이 소요되는 작업을 비동기적으로 처리하면서도, 메인 스레드를 차단하지 않습니다. 즉, 특정 루틴을 실행하다가 잠시 중지하고 다른 루틴을 실행할 수 있으며 완료 후 처음 루틴을 재개하여 연속으로 수행하는, 동시성 프로그램을 작성할 수 있습니다. 일반적으로 멀티 쓰래드 모델은 Deadlock 의 위험이 있기도하고, 쓰래드간에 작업 전환(컨텍스트 스위칭) 시 비용이 많이 발생합니다만, 코루틴은 이러한 위험과 오버헤드를 감소 시킬 수 있는 장점이 있습니다.
3. 동작방식
코루틴은 다음과 같은 방식으로 동작합니다.
1. 코루틴 함수 정의 : yield 를 사용한 Generator 함수를 정의
2. 실행 및 중단 : next() 함수 또는 입력값을 사용하여 값을 반환하고 중단합니다.
3. 코루틴 종료: 마지막 값을 반환하면 코루틴은 자동으로 종료 됩니다.
def simple_coroutine():
print("코루틴 시작")
x = yield "첫 번째 yield 지점" # 값을 반환하고 중단, 메인루틴에서 x 값을 입력받아 재개합니다.
print(f"받은 값: {x}")
y = yield "두 번째 yield 지점" # 값을 반환하고 중단, 메인루틴에서 y 값을 입력받아 재개합니다.
print(f"받은 값: {y}")
yield "코루틴 종료"
# 코루틴 객체 생성
coroutine = simple_coroutine()
# 코루틴 실행 및 중단 지점 확인
print(next(coroutine))
# 코루틴 시작, "첫 번째 yield 지점" 출력
print(coroutine.send(10))
# x에 10을 보내고, "두 번째 yield 지점" 출력
print(coroutine.send(20))
# y에 20을 보내고, "코루틴 종료" 출력
아래와 같이 코루틴 상태를 체크해 봅니다.
from inspect import getgeneratorstate
# 코루틴 객체 생성
coroutine = simple_coroutine()
print(getgeneratorstate(coroutine))
# GEN_CREATED
print(next(coroutine))
print(getgeneratorstate(coroutine))
# GEN_SUSPENDED
...
try:
print(coroutine.send(30))
except StopIteration:
print("Stop")
print(getgeneratorstate(coroutine)) #StopIteration exception을 발생 시키고 종료
# GEN_CLOSED
async ~ await 를 사용한 코루틴
1. 코루틴 함수 정의: async def 키워드를 사용하여 코루틴을 정의할 수 있습니다. 이 함수는 호출되었을 때 즉시 실행되지 않고, coroutine object를 반환합니다.
2. 실행 및 중단: 코루틴은 await 키워드를 사용해 다른 코루틴 또는 비동기 작업이 완료되기를 기다리면서 중단됩니다. 이렇게 중단된 코루틴은 이후에 재개할 수 있습니다.
3. 코루틴 종료: 코루틴은 완료되면 자동으로 종료됩니다. 다만, 종료 전 return 구문을 사용하면 값을 반환할 수 있습니다.
async ~ await 키워드에 대해서는 다음 블로그에서 더 자세히 알아보도록 하겠습니다.
코루틴은 특히 네트워크 요청이나 파일 입출력처럼 상대적으로 시간이 오래 걸리는 작업을 수행하는 데 매우 유용합니다. 동기 코드에서는 이런 작업들이 완료될 때까지 전체 프로그램이 멈추지만, 코루틴은 비동기적으로 이러한 작업을 처리하여, 다른 작업들이 동시에 실행될 수 있도록 합니다.
결론
파이썬의 코루틴은 비동기 프로그래밍을 간결하게 해주는 강력한 도구입니다. 특히 async와 await 키워드를 통해 복잡한 비동기 작업을 효율적으로 처리할 수 있습니다. 코루틴은 I/O 바운드 작업에서 특히 유용하며, 이벤트 루프를 통해 여러 코루틴을 관리하고 동시에 실행할 수 있습니다.