Threads

스레드 수명 책임

std::thread를 만들면 함수가 동시에 실행된다. join, detach, 공유 데이터 수명, 예외 전달을 정하지 않으면 종료 시점이 가장 먼저 깨진다.

01

작업 범위 결정

스레드 함수가 읽고 쓰는 데이터가 스레드보다 오래 살아 있는지 확인한다.

02

종료 정책 선택

join할지, jthread로 자동 정리할지, detach가 정말 필요한지 결정한다.

03

예외 경로 설계

스레드 함수 내부 예외는 호출 스레드로 자동 전파되지 않으므로 promise, future, 로그 정책이 필요하다.

std::thread
수동 join 필요 joinable 상태로 소멸하면 std::terminate가 호출된다.
RAII wrapper나 jthread가 안전하다.
std::jthread
자동 join 소멸 시 stop 요청 후 join을 수행한다.
협력적 취소에 적합하다.
인자 전달
기본은 복사 참조로 넘기려면 std::ref를 써야 하지만 수명 위험이 생긴다.
값 전달이 안전한 경우가 많다.
detach
관리 포기 프로세스 종료, 객체 수명, 오류 보고를 추적하기 어려워진다.
서비스성 작업에는 별도 소유 구조가 필요하다.

join 보장 · 참조 수명 · 예외 점검

join 보장 모든 코드 경로에서 join 또는 jthread 소멸이 보장되는가.
참조 수명 스레드가 지역 변수 참조를 들고 함수 밖까지 실행되지 않는가.
예외 스레드 내부 실패가 조용히 프로그램 종료로 이어지지 않도록 처리하는가.

jthread 사용

std::jthread worker([](std::stop_token st) {
    while (!st.stop_requested()) {
        poll_once();
    }
});