
코루틴(Coroutine)은 실행을 일시 중단(Suspend)했다가 나중에 적절한 지점에서 재개(Resume)할 수 있도록 설계된 루틴을 말한다.
언어별 구현 방식은 천차만별이다. 고유의 스택을 가지는지 여부에 따라 Stackful vs Stackless로 나뉘며, 코루틴이 병렬로 실행될 수 있는지도 설계에 따라 다르다. 흔히 코루틴이 병행성(Concurrency)을 제공한다고 생각하기 쉽지만, 비록 예외적인 경우라 할지라도 µC++의 사례처럼 별도의 실행 스레드 없이 호출자의 스레드를 빌려 쓰며 동기적(Synchronous)으로 동작하는 경우도 존재한다. 즉, 코루틴은 '병행 실행' 그 자체보다는 '제어 흐름의 유연한 양보'에 초점이 맞춰진 개념이다.
파이썬 같은 대중적인 언어에 공식 도입된 것이 2015년쯤이라, 10여 년 전 무렵에야 제안된 상당히 최신 개념일 거라 짐작했다. 하지만 코루틴은 역사적으로 상당히 오래된 개념이다. 이미 1958년에 Melvin Conway가 어셈블러의 Lexer와 Parser를 코루틴으로 구현하여 서로 데이터를 주고받게 만든 것이 최초의 사례라고 한다.
내가 코루틴을 처음 접한 건 오래전 'User-level Thread'를 다루던 수업에서였다. 당시에는 회사 실무에서 코루틴을 직접 써 본 적이 없었기에, 이런 수준 높은 프로그래밍 기법을 배웠다는 자만심도 있었다. 하지만 역시나 이후 실무에서 직접 활용할 기회가 없다 보니 이름만 기억할 뿐 본질은 점차 잊게 되었다. 그러다 최근 비동기 I/O를 처리하는 프로젝트를 진행하며 코루틴을 다시 마주하게 되었다. 이 글은 새로운 언어에서 코루틴을 마주할 미래의 나, 그리고 개념을 정리하고자 하는 이들을 위한 기록이다.
Co-routine의 접두사 'Co-'는 'Cooperative(협력적인)'라는 의미를 내포한다. 이는 스케줄링 관점에서 OS가 강제로 실행권을 뺏는 선점형(Preemptive) 방식이 아니라, 루틴이 스스로 제어권을 양보(Yield)하며 협력하는 비선점형(Non-preemptive) 방식이 코루틴의 본질임을 보여준다.
결국 실행 상태를 유지하며 제어권을 주고받는 것이 핵심 아이디어이며, 이를 위해 Suspend/Resume 메커니즘과 내부적인 상태(Active, Inactive, Terminated) 관리가 공통적으로 존재한다. 그 외의 세부 속성들은 각 언어가 필요에 따라 다르게 정의하고 구현했을 뿐이다.
한줄요약
코루틴의 본질: 중단 가능한 제어 흐름과 비선점형 스케줄링