기타 Hacker News · 2026-10-21

MS 레전드 개발자가 알기 쉽게 풀어쓴 C++ future의 내부 작동 원리

핵심 요약
  • 마이크로소프트의 레이먼드 첸이 std::future, std::promise 등 C++ 비동기 클래스들의 공통 기반이 되는 내부 상태 모델을 가상 코드로 정리했습니다.
  • 복잡해 보이는 C++ 비동기 요소들이 결국 '값 설정, 예외 설정, 대기, 값 추출'이라는 단일 source 구조로 귀결된다는 점을 직관적으로 보여줍니다.
  • 레이먼드 첸 본인도 자꾸 까먹어서 기억하려고 글을 쓴다는 솔직한 후기를 남겼으며, 댓글에서는 실제 표준 라이브러리 구현과의 디테일 차이에 대한 토론이 이어졌습니다.
요약 마이크로소프트의 베테랑 개발자 레이먼드 첸(Raymond Chen)이 자신의 블로그 'The Old New Thing'을 통해 C++ 표준 라이브러리의 비동기 처리 핵심 요소들을 설명하는 멘탈 모델 정리 시리즈를 시작했습니다. 그는 std::promise, std::packaged_task, std::async, std::future, std::shared_future 같은 도구들이 실은 표준 라이브러리 내부에서 '상태(state)'라고 불리는 단 하나의 공통 메커니즘을 기반으로 구현되어 있다고 설명합니다. 글에서는 이해를 돕기 위해 C#의 task completion source와 유사한 개념으로서 이를 'source'라는 가상의 구조체로 정의해 구조를 풀어나갔습니다. 이 가상 'source' 구조체는 판별자(discriminant), 값 또는 예외를 담는 공용체(union), 그리고 스레드 안전성을 보장하는 뮤텍스와 대기를 위한 조건 변수(condition variable)로 구성됩니다. 핵심 동작은 단순하게 네 가지로 나뉩니다. 첫째, 비어있는 상태에서만 값을 설정하는 `set_value`. 둘째, 예외를 저장하는 `set_exception`. 셋째, 결과가 준비될 때까지 기다리는 `wait` 및 `wait_for`. 넷째, 값을 꺼내거나 예외를 다시 던지는 `get`과 값을 이동시키며 소비 상태로 변경하는 `consume`입니다. 그는 값이 이미 채워졌는데 또 설정하려고 하면 오류를 던지고, 한 번 소비된 값을 다시 꺼내려 할 때도 예외를 던지도록 설계 원리를 설명했습니다. 또한 union 때문에 소멸자를 직접 작성하는 것은 다소 귀찮은 작업이라며 독자의 몫으로 남겨두었고, 자신이 이 시리즈를 작성하는 진짜 이유에 대해 "나 역시 작동 방식을 자꾸 까먹기 때문에 정리하면서 기억하려는 것"이라는 유쾌한 코멘트를 덧붙였습니다.
해외 반응 번역
사소한 오타 발견: "values an exceptions"는 "values and exceptions"여야 할 것 같습니다.
참고로 실제 표준 라이브러리에서는 실무상 `future_already_retrieved`를 던지지 않습니다. 왜 에러 열거형에 넣어놨나 싶었는데 그냥 이유 없이 들어간 거였더군요. 이미 값을 꺼낸 future에 `std::future::get`을 호출하면 실제로는 `no_state` 예외가 발생합니다. 따라서 예시의 'consumed' 열거값은 실제 구현에서는 쓰이지 않고, 값을 가져가면 source가 파괴되거나 shared future를 위해 그대로 유지됩니다.
Sponsored · 광고