흔히 코틀린을 사용할 때 자주 만날 수 있는 단어인 코루틴, 깊게 알아보자.
코루틴이란 Co (ooperation 협동) + routine (루틴) 단어가 합쳐져 생긴 개념이다.
스레드처럼 백그라운드 작업을 위임할 때 많이 사용되는데, 이는 코틀린 뿐만 아니라 여러 언어에서도 통용된다. (Rust 비동기 모델, Go 등등..) 결국 코루틴은 하나의 비동기 프로그래밍을 위한 추상화 도구이기 때문이다.
코루틴이 어떻게 구현되는지 살펴보자. 일반적으로 코루틴은 내부적으로 상태 머신(state machine)을 사용한다.
상태 머신이란 여러 상태(state)를 가지고 있으며, 특정 조건에 따라 상태 간 전환이 이루어지는 시스템을 뜻한다. 코루틴은 실행 중에 여러 상태를 거치며, 각 상태에서 일시 중단되고 다시 시작될 수 있다.
상태 머신을 다루는 방법 중에 대표적으로 두가지 방법으로 나뉜다. 스택리스 코루틴과 스택풀 코루틴이다.
스택리스 코루틴은 상태를 저장함과 동시에 힙으로 변수 값과 실행 위치(몇 번째에서 중단되는지)이 저장된다. 스택을 사용하지 않기 때문에 상대적으로 컨텍스트 스위치 비용도 적고, 메모리 용량도 작아지고 효율적이다.
스택풀 코루틴은 상태를 저장할 때 스택째로 저장하는 방법이다. 용량도 더 들고, 재귀 함수에서 잘못 사용 시 스택오버플로우가 발생한다. 다만, 일반 함수랑 동일한 원리로 동작하기 때문에 디버깅이 편리하다는 장점이 있다.
상태 머신은 일반적으로 시스템 콜(syscall)로 제어한다. 거의 코루틴의 핵심이라고 봐도 무방하다.
애플리케이션에서 스레드를 사용하진 않지만, I/O 작업이 발생하면 OS에 해당 작업 스레드를 위임한다. 그리고, 시스템 콜에 해당 작업이 완료되면 이벤트를 보내달라고 요청한다. 그리고 이벤트가 내려지기까지 기다린다. (상태 머신이 상태가 바뀔 때까지 기다림) 이벤트가 내려지면 해당 작업을 다시 재개하는 방식이다.
다음은 운영체제별 메커니즘이다.
위와 같이 운영체제마다 조금씩 차이가 있지만 동일한 메커니즘으로 이벤트를 내려준다.