"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
👨💻 안녕하세요, 윌리 프로젝트의 윌리 입니다.
C++ 에서 thread 의 join() 은 무엇이며, 어떻게 활용할 수 있는지 간략히 알아보았습니다.
질문 >
C++ 에서 thread 의 join() 은 무엇이며, 어떻게 활용할 수 있나요?
답변 >
std::thread::join()란?
C++에서 std::thread::join()은 멀티스레드 동기화를 위한 함수로, 호출한 스레드가 대상 스레드가 종료될 때까지 기다리도록 하는 기능을 제공합니다. 스레드가 수행 중인 작업을 마칠 때까지 블록(block) 상태로 대기하여, 스레드 간의 작업 순서를 보장합니다.
std::thread::join()의 특징
- 동기화 보장:
- join()을 호출한 스레드는 대상 스레드가 종료될 때까지 대기합니다.
- 이로 인해, 스레드의 작업이 모두 완료된 후 다음 작업이 실행됩니다.
- 단일 호출 제한:
- 한 스레드에 대해 join()은 단 한 번만 호출할 수 있습니다.
- 두 번째 호출 시 std::system_error 예외가 발생합니다.
- 자원 해제:
- join()은 스레드가 종료된 후에 시스템 자원을 해제합니다.
- join() 없이 스레드 객체가 소멸되면, 프로그램은 비정상 종료됩니다.
- 비차단 호출 대비:
- join()은 호출 스레드가 종료될 때까지 기다리므로, 비동기로 스레드가 동작하도록 하고 싶다면 detach()를 사용할 수 있습니다.
기본 사용법
1. 단일 스레드의 join() 사용
#include <iostream>
#include <thread>
void worker() {
std::cout << "Worker thread is running." << std::endl;
}
int main() {
std::thread t(worker); // 새로운 스레드 생성
t.join(); // 메인 스레드는 worker 스레드가 종료될 때까지 대기
std::cout << "Worker thread has finished." << std::endl;
return 0;
}
출력 예시:
Worker thread is running.
Worker thread has finished.
활용 예제
2. 멀티스레드와 join()
#include <iostream>
#include <thread>
void worker(int id) {
std::cout << "Thread " << id << " is starting." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread " << id << " has finished." << std::endl;
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join(); // t1 스레드 종료 대기
t2.join(); // t2 스레드 종료 대기
std::cout << "Both threads have finished." << std::endl;
return 0;
}
출력 예시:
Thread 1 is starting.
Thread 2 is starting.
Thread 1 has finished.
Thread 2 has finished.
Both threads have finished.
3. 벡터를 사용한 다중 스레드 관리
#include <iostream>
#include <thread>
#include <vector>
void worker(int id) {
std::cout << "Thread " << id << " is working." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread " << id << " is done." << std::endl;
}
int main() {
const int numThreads = 3;
std::vector<std::thread> threads;
// 여러 스레드 생성
for (int i = 0; i < numThreads; ++i) {
threads.emplace_back(worker, i);
}
// 모든 스레드 join
for (auto& t : threads) {
t.join();
}
std::cout << "All threads are done." << std::endl;
return 0;
}
출력 예시:
Thread 0 is working.
Thread 1 is working.
Thread 2 is working.
Thread 0 is done.
Thread 1 is done.
Thread 2 is done.
All threads are done.
join()와 detach()의 차이
특징 | join() | detach() |
동작 방식 | 호출 스레드가 종료될 때까지 대기 | 호출 스레드를 분리하여 백그라운드에서 실행 |
자원 해제 | 스레드 작업이 끝난 후 자원을 해제 | 스레드가 종료될 때 시스템이 자원을 자동 해제 |
사용 사례 | 스레드 종료를 기다려야 하는 작업 | 비동기로 실행되어도 되는 경우 |
제약 조건 | 스레드 종료를 보장 | 백그라운드 작업이 완료되지 않을 수 있음 |
주의사항
- join() 또는 detach() 호출 필수:
- std::thread 객체가 소멸되기 전에 반드시 join()이나 detach()를 호출해야 합니다.
- 그렇지 않으면 프로그램이 **std::terminate*를 호출합니다.
- 중복 호출 금지:
- 한 스레드 객체에 대해 join()이나 detach()를 두 번 호출할 수 없습니다.
#include <iostream>
#include <thread>
void worker() {
std::cout << "Worker thread is running." << std::endl;
}
int main() {
std::thread t(worker);
t.join();
// t.join(); // 두 번째 호출 시 예외 발생 (std::system_error)
return 0;
}
- 스레드 종료 후 호출:
- 스레드가 이미 종료된 경우에도 join() 호출은 정상적으로 작동합니다.
결론
std::thread::join()은 멀티스레드 프로그래밍에서 스레드 동기화를 보장하며, 스레드가 작업을 완료하기 전에는 호출 스레드가 진행되지 않도록 설계되었습니다. 이는 스레드 간의 작업 순서를 보장하고 자원을 안전하게 관리하기 위해 필수적인 도구입니다.
- 사용 사례:
- 스레드 종료를 기다려야 하는 작업(예: 데이터 처리 완료 후 결과 출력).
- 동기화가 필요한 멀티스레드 환경.
- 대안:
- 스레드가 백그라운드에서 비동기로 실행되길 원한다면 detach()를 사용할 수 있습니다.
join()은 스레드 관리와 동기화의 핵심이며, 이를 통해 안정적이고 효율적인 멀티스레드 프로그램을 작성할 수 있습니다.
🎬 유튜브 채널 🎬
위로그@WiLog
📢 안녕하세요, 위로그@WiLog 시청자 여러분, 저는 윌리(Willee) 입니다. 📢 위로그@WiLog 는 자기계발을 목적으로 하는 채널 입니다. 📢 오늘도 즐겁게~ 자신을 위한 계발을 함께 해보아요~ d^_^b 📌
www.youtube.com
🎬 치지직 채널 🎬
위로그 채널 - CHZZK
지금, 스트리밍이 시작됩니다. 치지직-
chzzk.naver.com
'프로그래밍' 카테고리의 다른 글
👨💻 [C++] C++ 에서 std::condition_variable 은 무엇이며, 어떻게 활용할 수 있나요? (0) | 2025.01.23 |
---|---|
👨💻 [C++] C++ 에서 thread 의 joinable() 은 무엇이며, 어떻게 활용할 수 있나요? (0) | 2025.01.23 |
👨💻 [C++] C++ 에서 std::this_thread::get_id() 는 무엇이고, 어떻게 활용할 수 있나요? (0) | 2025.01.23 |
👨💻 [Go] Go 에서 Singleton 디자인 패턴은 어떻게 설계할 수 있나요? (0) | 2025.01.22 |
👨💻 [Go] GoLand 의 설정 중 Run Targets 의 Go Executable 과 GOPATH 는 무엇인가요? (0) | 2025.01.22 |