데이터과학 삼학년

코루틴 (coroutine) 정리 본문

Python

코루틴 (coroutine) 정리

Dan-k 2021. 1. 1. 14:42
반응형

코루틴 (coroutine) 이란 cooperative routine을 의미하며, 서로 협력하는 루틴이라는 뜻이다.

메인 루틴과 서브 루틴처럼 종속된 관계가 아닌 대등한 관계로 동작되며, 특정시점마다 상대방의 코드를 실행 시킨다.

즉, 동시성 프로그램을 가능하도록 한 기술이라고 보면 된다.

- main routine 이 대기중일때,  sub routine을 통해 연산이후 다시 main routine으로 돌아오도록 하는 기술

 그림 41-2 코루틴의 동작 과정

위 그림처럼 코루틴은 함수가 종료되지 않은 상태에서 메인 루틴의 코드를 실행한 뒤 다시 돌아와서 코루틴의 코드를 실행한다.

 

일반 함수를 호출하면 코드를 한 번만 실행할 수 있지만, 코루틴은 코드를 여러 번 실행할 수 있습니다.

참고로 함수의 코드를 실행하는 지점을 진입점(entry point)이라고 하는데, 코루틴은 진입점이 여러 개인 함수입니다.

 

코루틴에 값 보내기

코루틴은 제너레이터의 특별한 형태로, 제너레이터에서 yield 를 이용해 값을 발생시켰다면, 

코루틴에선 (yield) 형식을 통해 값을 받아올 수 있다.

  • 코루틴객체.send(값)
  • 변수 = (yield)

코드

def number_coroutine():
    while True:        # 코루틴을 계속 유지하기 위해 무한 루프 사용
        x = (yield)    # 코루틴 바깥에서 값을 받아옴, yield를 괄호로 묶어야 함
        print(x)
 
co = number_coroutine()
next(co)      # 코루틴 안의 yield까지 코드 실행(최초 실행)
 
co.send(1)    # 코루틴에 숫자 1을 보냄
co.send(2)    # 코루틴에 숫자 2을 보냄
co.send(3)    # 코루틴에 숫자 3을 보냄

##===
1
2
3

 

코루틴은 while 을 이용해 무한 루프를 통해 메인 루틴을 유지하고, 코루틴 바깥에서, 코루틴에 값을 보내는 형태로 이루어진다.

 그림 41-3 코루틴의 코드를 최초로 실행한 뒤 메인 루틴으로 돌아옴

 

코루틴을 무한루프 상태에서 종료 시키는 방법은 간단하다.

객체.close() 를 선언해주면 된다

def number_coroutine():
    while True:
        x = (yield)
        print(x, end=' ')
 
co = number_coroutine()
next(co)
 
for i in range(20):
    co.send(i)
 
co.close()    # 코루틴 종료

##===
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

 

GeneratorExit 예외 처리하기

코루틴 객체에서 close 메서드를 호출하면 종료될때 GeneratorExit 예외가 발생하게 된다.

따라서 이 예외를 처리하게 되면, 코루틴의 종료시점을 파악 할 수 있다.

def number_coroutine():
    try:
        while True:
            x = (yield)
            print(x, end=' ')
    except GeneratorExit:    # 코루틴이 종료 될 때 GeneratorExit 예외 발생
        print()
        print('코루틴 종료')
 
co = number_coroutine()
next(co)
 
for i in range(20):
    co.send(i)
 
co.close()

##===
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
코루틴 종료

 

 

코루틴 안에서 예외 발생시키기

코루틴 안에서 예외를 발생시킬 때는 throw 메서드를 사용한다.

def sum_coroutine():
    try:
        total = 0
        while True:
            x = (yield)
            total += x
    except RuntimeError as e:
        print(e)
        yield total    # 코루틴 바깥으로 값 전달
 
co = sum_coroutine()
next(co)
 
for i in range(20):
    co.send(i)
 
print(co.throw(RuntimeError, '예외로 코루틴 끝내기')) # 190
                                                 # 코루틴의 except에서 yield로 전달받은 값
                                                 
##===
예외로 코루틴 끝내기
190

 

하위 코루틴의 반환값 가져오기

코루틴에서 yield from 에 코루틴을 지정하면 해당 코루틴에서 return 반환값을 가져옴

  • 변수 = yield from 코루틴()
def accumulate():
    total = 0
    while True:
        x = (yield)         # 코루틴 바깥에서 값을 받아옴
        if x is None:       # 받아온 값이 None이면
            return total    # 합계 total을 반환
        total += x
 
def sum_coroutine():
    while True:
        total = yield from accumulate()    # accumulate의 반환값을 가져옴
        print(total)
 
co = sum_coroutine()
next(co)
 
for i in range(1, 11):    # 1부터 10까지 반복
    co.send(i)            # 코루틴 accumulate에 숫자를 보냄
co.send(None)             # 코루틴 accumulate에 None을 보내서 숫자 누적을 끝냄
 
for i in range(1, 101):   # 1부터 100까지 반복
    co.send(i)            # 코루틴 accumulate에 숫자를 보냄
co.send(None)             # 코루틴 accumulate에 None을 보내서 숫자 누적을 끝냄

##===
55
5050

 

 

출처:dojang.io/mod/page/view.php?id=2418

 

파이썬 코딩 도장: 41.1 코루틴에 값 보내기

Unit 41. 코루틴 사용하기 지금까지 함수를 호출한 뒤 함수가 끝나면 현재 코드로 다시 돌아왔습니다. 예를 들어서 다음과 같이 calc 함수 안에서 add 함수를 호출했을 때 add 함수가 끝나면 다시 calc

dojang.io

 

728x90
반응형
LIST
Comments