보통 아래와 같이 메인루틴 안의 서브루틴들로 구성된 기능에 익숙할 것이다. 주로 구현한 함수들은 한 번 실행되고 종료되는 함수들이었다. Python의 서브루틴은 이러한 서브 루틴의 사용을 조정하는 메인 함수에 의해서 호출된다.
Coroutine
Python의 코루틴(Coroutine)이란 Cooperative Routine을 의미하며, 서로 협력하는 루틴이라는 뜻이다. 메인루틴과 서브루틴처럼 종속된 관계가 아니라 대등한 관계로서 동작하며, 특정시점마다 상대방의 코드를 실행한다. 즉, 동시성 프로그램을 가능하도록 한 기술이라고 이해하면 될 것이다.
( Main Routine이 대기중일 때, Sub Routine을 통해 연산한 이후에 다시 Main Routine으로 돌아오도록 하는 기술 )
위의 그림처럼 Coroutine은 함수가 종료되지 않은 상태로 메인 루틴의 코드를 실행한 뒤 다시 돌아와서 코루틴의 코드를 실행하게 되는 것이다. 일반 함수를 호출하면 코드를 한 번만 실행할 수 있지만, 코루틴은 코드를 여러 번 실행할 수 있는 것이다. 참고로 함수의 코드를 실행하는 지점을 진입점(Entry Point)라고 하는데, 코루틴은 진입점이 여러개인 함수인 것이다.
Coroutine에 값 보내기
코루틴(Coroutine)은 제너레이터(Generator)의 특별한 형태로, 제너레이터에서 yield를 이용해 값을 발생시켰다면, 코루틴에선 (yield) 형식을 통해 값을 받아올 수 있다.
- 코루틴객체.send(값)
- 변수 = (yield)
def number_coroutine():
while Ture: # 코루틴을 계속 유지하기 위해서 무한루프 사용
x = (yield) # 코루틴 외부에서 값을 받아옴, yield를 괄호로 묶어야 한다.
print(x)
co = number_coroutine()
next(co) # 코루틴 안의 yield까지 코드 실행(최초실행)
co.send(1) # 코루틴에 숫자 1을 보냄
co.send(2) # 코루틴에 숫자 2을 보냄
co.send(3) # 코루틴에 숫자 3을 보냄
코루틴은 while을 이용한 무한 루프를 통해 메인 루틴을 유지하고, 코루틴 외부에서 코루틴에 값을 보내는 형태로 이루어진다. 또한 코루틴을 무한루프상태에서 종료하기 위해서는 객체.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() Method를 호출하면 종료될 때 GeneratorExit 예외가 발생하게 된다. 따라서 이 예외를 처리하면 코루틴의 종료시점을 파악할 수 있다.
def number_coroutine():
try:
while Ture:
x = (yield)
print(x, end=' ')
except GeneratorExit #코루틴이 종료될 때 GeneratorExit 예외 발생
print()
print('코루틴 종료')
co = number_coroutine()
next(co)
for i in rnage(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
# 코루틴 종료
Coroutine과 스레드의 차이점
스레드는 비동기로, 여러 스레드가 있다면 한꺼번에 동시에 실행되는 반면, 코루틴은 프로그램이 실행 중일 때 특정 시점에 코루틴으로 이동하고 그 전에 진행 중이던 루틴은 정지합니다. 즉, 한번에 하나의 코드만 실행됩니다. 이는 기존의 프로그래밍과 유사한 성격으로 보일 수 있습니다. 하지만 기존의 프로그래밍은 에러가 나지 않는 이상 실행 중인 코드를 빠져나올 수 있는 부분은 return과 같이 가장 마지막 부분이지만 코루틴은 실행 중간에 해당 함수를 빠져 나와 다른 코드를 실행할 수 있고 다시 실행 중이였던 코드 라인으로 이동할 수도 있습니다. 다시 말해서 코루틴은 yield 키워드로 실행을 중지할 수 있고 yield 키워드를 호출했던 곳으로 와서 실행을 재 시작합니다.
싱글코어에선 코루틴은 이동 시점이 더 잘 조절되고 context switching이 적어 성능면에서 멀티 스레드보다 좋을 수 있지만 멀티코어 프로세서를 활용할 수 없다는 문제점이 있으며 스레드보다 성능이 떨어지게 됩니다.
'Python 프로그래밍' 카테고리의 다른 글
[Python] Asyncio (0) | 2022.06.05 |
---|---|
[Python] GIL (0) | 2022.06.03 |
[Python] Future (0) | 2022.06.01 |
[Python] Object Reference (0) | 2022.05.27 |
[Python] mutable과 immutable (0) | 2022.05.26 |