코루틴 사용하기

Tasker_Jang·2026년 2월 27일

1. 서브 루틴 vs 코루틴

일반적인 함수 호출 방식을 서브 루틴(Subroutine) 이라고 합니다. 메인 루틴이 서브 루틴을 호출하면 서브 루틴의 코드를 실행한 뒤 메인 루틴으로 돌아오며, 서브 루틴이 끝나면 그 안의 내용은 모두 사라집니다. 즉, 메인 루틴에 종속된 관계입니다.

반면 코루틴(Coroutine)Cooperative Routine, 즉 서로 협력하는 루틴을 의미합니다. 메인과 서브가 종속된 관계가 아니라 대등한 관계로, 특정 시점에 상대방의 코드를 실행하며 서로 값을 주고받습니다.

구분서브 루틴코루틴
관계메인에 종속대등한 관계
진입점1개여러 개
실행 횟수한 번여러 번
상태 유지❌ 종료 시 소멸✅ 중단 상태 유지
값 전달반환값만양방향 주고받기

2. 코루틴 기본 문법

코루틴은 함수 안에서 (yield) 형식으로 yield를 괄호로 묶어 변수에 저장합니다. 이렇게 하면 send()로 보낸 값을 받아올 수 있습니다.

def my_coroutine():
    while True:
        value = (yield)          # send()로 보낸 값을 받음
        print(f"받은 값: {value}")

co = my_coroutine()
next(co)          # 코루틴 첫 실행 — yield 지점까지 진행 (초기화)

co.send(10)       # 받은 값: 10
co.send(20)       # 받은 값: 20
co.send(30)       # 받은 값: 30

코루틴을 처음 사용할 때는 반드시 next()를 한 번 호출해서 첫 번째 yield 지점까지 진행시켜야 합니다. 이 과정을 코루틴 초기화(프라이밍, Priming) 라고 합니다.


3. 제너레이터 vs 코루틴

둘 다 yield를 사용하지만 값을 다루는 방향이 다릅니다.

# 제너레이터: next()를 반복 호출해서 값을 꺼냄
def number_gen():
    yield 1
    yield 2
    yield 3

gen = number_gen()
print(next(gen))  # 1
print(next(gen))  # 2

# 코루틴: next()로 초기화 후 send()로 값을 주고받음
def accumulator():
    total = 0
    while True:
        value = (yield total)    # total을 내보내고 value를 받음
        total += value

co = accumulator()
print(next(co))     # 0  (초기화)
print(co.send(10))  # 10
print(co.send(20))  # 30
print(co.send(5))   # 35
구분제너레이터코루틴
값 흐름바깥으로 전달 (단방향)양방향 주고받기
주요 메서드next() 반복 호출next() 1회 후 send() 사용
주요 용도데이터 생성, 순회비동기 작업, 데이터 처리 파이프라인

4. close()와 throw()

close() — 코루틴 강제 종료

close()를 호출하면 코루틴이 종료되면서 GeneratorExit 예외가 발생합니다. 필요하다면 try/finally로 종료 시 정리 작업을 수행할 수 있습니다.

def my_coroutine():
    try:
        while True:
            value = (yield)
            print(f"받은 값: {value}")
    except GeneratorExit:
        print("코루틴이 종료됩니다.")   # 종료 시 정리 작업

co = my_coroutine()
next(co)

co.send(1)    # 받은 값: 1
co.close()    # 코루틴이 종료됩니다.

throw() — 코루틴 안에 예외 발생시키기

throw()는 코루틴 안에 예외를 던집니다. 말 그대로 "예외를 던진다"는 의미입니다.

# 코루틴객체.throw(예외이름, 에러메시지)
def my_coroutine():
    while True:
        try:
            value = (yield)
            print(f"받은 값: {value}")
        except ValueError as e:
            print(f"예외 처리: {e}")

co = my_coroutine()
next(co)

co.send(10)                          # 받은 값: 10
co.throw(ValueError, "잘못된 값!")   # 예외 처리: 잘못된 값!
co.send(20)                          # 받은 값: 20

5. yield from으로 코루틴 값 가져오기

yield from에 코루틴을 지정하면 해당 코루틴이 return으로 반환한 값을 가져올 수 있습니다. 코루틴도 제너레이터이므로 return을 사용하면 StopIteration이 발생하며, yield from은 이 값을 자동으로 받아옵니다.

def sub_coroutine():
    x = (yield)
    y = (yield)
    return x + y          # StopIteration과 함께 반환값 전달

def main_coroutine():
    result = yield from sub_coroutine()   # 반환값을 자동으로 받아옴
    print(f"최종 결과: {result}")

co = main_coroutine()
next(co)
co.send(10)
co.send(20)   # 최종 결과: 30
profile
ML Engineer 🧠 | AI 모델 개발과 최적화 경험을 기록하며 성장하는 개발자 🚀 The light that burns twice as bright burns half as long ✨

0개의 댓글