C++20 jthread와 stop_token — 협력적 스레드 취소
C++20은 std::thread의 두 가지 문제를 해결한 std::jthread를 도입했습니다.
- 자동 join: 소멸자에서 자동으로
join()을 호출합니다. - 협력적 취소:
std::stop_token으로 스레드에 취소 요청을 보낼 수 있습니다.
1. 기본 사용 — 자동 join
섹션 제목: “1. 기본 사용 — 자동 join”#include <thread>#include <chrono>#include <iostream>
void task() { std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << "완료\n";}
int main() { std::jthread t(task); // 소멸자에서 자동 join — join() 호출 불필요}2. stop_token으로 협력적 취소
섹션 제목: “2. stop_token으로 협력적 취소”#include <thread>#include <chrono>#include <iostream>
void worker(std::stop_token st) { while (!st.stop_requested()) { std::cout << "작업 중...\n"; std::this_thread::sleep_for(std::chrono::milliseconds(200)); } std::cout << "취소 요청 수신, 종료\n";}
int main() { std::jthread t(worker); std::this_thread::sleep_for(std::chrono::seconds(1)); t.request_stop(); // 취소 요청 전송 // 소멸자에서 자동 join}3. stop_callback — 취소 시 정리 작업
섹션 제목: “3. stop_callback — 취소 시 정리 작업”#include <thread>#include <mutex>#include <condition_variable>
std::mutex mtx;std::condition_variable_any cv;
void worker(std::stop_token st) { // 취소 요청 시 condition_variable을 깨움 std::stop_callback cb(st, [&] { cv.notify_all(); });
std::unique_lock lock(mtx); cv.wait(lock, st, [] { return false; }); // stop_token 인식 대기 std::cout << "대기 해제\n";}
int main() { std::jthread t(worker); std::this_thread::sleep_for(std::chrono::milliseconds(500)); t.request_stop();}4. stop_source 공유
섹션 제목: “4. stop_source 공유”#include <thread>#include <vector>#include <iostream>
int main() { std::stop_source src;
std::vector<std::jthread> workers; for (int i = 0; i < 4; ++i) { workers.emplace_back([i](std::stop_token st) { while (!st.stop_requested()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } std::cout << "워커 " << i << " 종료\n"; }, src.get_token()); // 공유 토큰 전달 }
std::this_thread::sleep_for(std::chrono::milliseconds(500)); src.request_stop(); // 모든 워커에 취소 요청}5. std::thread vs std::jthread
섹션 제목: “5. std::thread vs std::jthread”| 항목 | std::thread | std::jthread |
|---|---|---|
| 소멸자 동작 | std::terminate() 호출 | 자동 join() |
| 취소 지원 | 없음 | stop_token |
| join 필요 | 필수 | 불필요 |
| 사용 가능 버전 | C++11 | C++20 |
6. 실전 패턴: 백그라운드 서비스
섹션 제목: “6. 실전 패턴: 백그라운드 서비스”class BackgroundService { std::jthread thread_;
void run(std::stop_token st) { while (!st.stop_requested()) { process(); std::this_thread::sleep_for(std::chrono::seconds(1)); } }
void process() { /* 실제 작업 */ }
public: void start() { thread_ = std::jthread([this](std::stop_token st) { run(st); }); } void stop() { thread_.request_stop(); }};std::jthread는 RAII 기반 자동 join과 협력적 취소를 제공해 스레드 생명주기 관리를 크게 단순화합니다. 새 코드에서는 std::thread 대신 std::jthread를 기본으로 사용하세요.