
C++ 코루틴, 왜 이렇게 복잡한 걸까?
C++20에서 코루틴이 정식으로 들어왔는데요, 써보신 분들은 아시겠지만... 솔직히 처음 보면 "이게 대체 왜 이렇게 생겼지?"라는 생각이 드는 게 정상이에요. Python이나 JavaScript의 async/await처럼 깔끔하고 직관적인 걸 기대하면, C++의 코루틴 인터페이스를 보는 순간 당황하게 되거든요. promise_type이 뭐고, co_await은 뭐고, awaiter는 또 뭐냐... 개념이 겹겹이 쌓여있어요.
한 C++ 개발자가 Unity 게임 엔진의 내부 구조를 살펴보다가, 이 복잡함의 이유를 비로소 이해하게 됐다는 블로그 글을 썼는데요, 그 과정이 꽤 흥미로워요.
코루틴이 뭔지부터 짚고 가볼게요
코루틴은 쉽게 말해서 실행을 중간에 멈췄다가 나중에 다시 이어서 할 수 있는 함수예요. 일반 함수는 호출하면 끝까지 쭉 실행되잖아요? 코루틴은 중간에 "여기서 잠깐 멈출게"라고 할 수 있어요. 게임에서 "3초 대기 후 폭발" 같은 로직을 짤 때 이게 정말 유용하거든요.
Unity를 써본 분이라면 C#의 코루틴을 잘 아실 거예요. yield return new WaitForSeconds(3f); 이런 식으로 쓰는 거요. 이게 직관적이고 편하죠. 근데 C++의 코루틴은 왜 이렇게 안 생겼냐는 게 많은 사람들의 의문이었어요.
Unity 내부에서 발견한 힌트
블로그 저자가 Unity 엔진의 C++ 코드를 살펴보니, Unity 내부에서는 C#의 그 간편한 코루틴과 비슷한 패턴을 C++로도 구현하고 있었대요. 근데 C++ 코루틴의 설계가 왜 그렇게 복잡한지를 보면, Unity 같은 게임 엔진 수준의 정밀한 제어가 필요하기 때문이라는 걸 깨달았다고 해요.
핵심은 이거예요. C++의 코루틴이 복잡한 이유는 "어떻게 멈추고, 어떻게 다시 시작할지"를 프로그래머가 완전히 제어할 수 있게 설계됐기 때문이에요. 메모리를 어디에 할당할지, 코루틴이 멈췄을 때 실행 컨텍스트를 어떻게 저장할지, 다시 깨울 때 어떤 스레드에서 실행할지... 이런 걸 전부 커스터마이즈할 수 있거든요.
Python의 async/await은 이런 결정을 언어와 런타임이 알아서 해줘요. 편하지만, 그만큼 제어권이 없어요. 반면 C++은 "우리는 게임 엔진도 만들고, 운영체제도 만들고, 임베디드 시스템도 만드는 언어야. 그러니까 이런 결정을 프로그래머한테 맡겨야 해"라는 철학인 거죠.
구체적으로 뭐가 다른가
예를 들어볼게요. Unity 게임에서 코루틴이 "다음 프레임까지 기다려"라고 했을 때, 이 코루틴을 다시 깨우는 건 Unity의 메인 게임 루프가 담당해요. 반면 서버 프로그램에서 "네트워크 응답이 올 때까지 기다려"라고 하면, 이건 OS의 I/O 이벤트 시스템이 깨워야 하고요.
C++의 코루틴 설계에서 co_await 뒤에 어떤 타입이든 올 수 있고, 그 타입의 await_suspend 메서드가 "멈추면 뭘 할지"를 정의하는 이유가 바로 이거예요. 게임 엔진이냐, 네트워크 서버냐, 임베디드 시스템이냐에 따라 "멈추고 깨우는 방식"이 완전히 달라야 하니까요. 이 유연성이 겉보기 복잡함의 원인이자, 동시에 C++이 그 많은 분야에서 쓰일 수 있는 이유이기도 해요.
다른 언어와 비교하면
Rust도 비슷한 고민을 했어요. Rust의 async/await도 런타임을 내장하지 않고, tokio 같은 외부 런타임을 선택해서 쓰는 구조거든요. "런타임의 동작을 프로그래머가 결정한다"는 점에서 C++과 철학이 비슷해요. 반면 Go는 goroutine이라는 걸 쓰는데, 이건 언어가 런타임을 통째로 제공하는 방식이에요. 편하지만, Go 런타임이 하는 방식 외에는 선택지가 없죠.
결국 편의성 vs 제어권의 스펙트럼에서 각 언어가 다른 지점을 선택한 거예요. C++은 극단적으로 제어권 쪽을 택한 것이고요.
한국 개발자에게 주는 시사점
국내에서도 언리얼 엔진을 쓰는 게임 개발사가 많고, C++을 주력으로 쓰는 시스템 프로그래밍 분야도 건재하죠. C++20 코루틴은 아직 실무에서 적극 도입되진 않았지만, 점점 라이브러리들이 지원을 늘려가고 있어요. 특히 비동기 I/O 라이브러리나 게임 엔진 쪽에서요.
만약 "코루틴 공부해야 하나 말아야 하나" 고민이시라면, 이 글의 관점이 도움이 될 거예요. 코루틴의 문법을 외우는 게 아니라, "왜 이렇게 설계됐는지"를 먼저 이해하면 그 복잡한 인터페이스가 갑자기 논리적으로 보이기 시작하거든요.
정리
C++의 코루틴이 복잡한 건 버그가 아니라 의도된 설계예요. 게임 엔진부터 운영체제까지, 완전히 다른 환경에서 동작해야 하는 언어이기 때문이죠. 여러분은 코루틴을 처음 접했을 때 어떤 언어에서 시작하셨나요? 그리고 C++의 이런 "전부 직접 결정하라" 스타일에 대해 어떻게 생각하시나요?
🔗 출처: Hacker News
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공