std::thread 클래스
std::thread
클래스는 C++11 표준 라이브러리에서 제공하는 멀티스레딩을 위한 클래스입니다. 이를 통해 쉽게 스레드를 생성하고 관리할 수 있습니다.
std::thread의 주요 함수
- 생성자: 새로운 스레드를 생성합니다.
- join(): 스레드가 종료될 때까지 대기합니다.
- detach(): 스레드를 분리하여 백그라운드에서 실행되도록 합니다.
- joinable(): 스레드가 join 또는 detach 가능한 상태인지 확인합니다.
예제 코드
#include <iostream>
#include <thread>
void threadFunction() {
std::cout << "Hello from thread!" << std::endl;
}
int main() {
std::thread t(threadFunction); // 스레드 생성
t.join(); // 메인 스레드가 생성된 스레드가 종료될 때까지 대기
return 0;
}
동기화 기법
여러 스레드가 공유 자원에 접근할 때, 동기화가 필요합니다. C++ 표준 라이브러리는 동기화를 위한 여러 도구를 제공합니다.
std::mutex
뮤텍스는 상호 배제를 구현하는 동기화 도구입니다. 뮤텍스를 사용하여 공유 자원에 대한 접근을 동기화할 수 있습니다.
예제 코드
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void printMessage(const std::string& msg) {
std::lock_guard<std::mutex> lock(mtx); // 뮤텍스 잠금
std::cout << msg << std::endl;
}
int main() {
std::thread t1(printMessage, "Hello from thread 1");
std::thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
std::lock_guard
std::lock_guard
는 뮤텍스를 자동으로 잠그고 해제하는 RAII(Resource Acquisition Is Initialization) 스타일의 동기화 도구입니다.
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void safeIncrement(int& counter) {
std::lock_guard<std::mutex> lock(mtx); // 뮤텍스 잠금
++counter;
}
int main() {
int counter = 0;
std::thread t1(safeIncrement, std::ref(counter));
std::thread t2(safeIncrement, std::ref(counter));
t1.join();
t2.join();
std::cout << "Counter value: " << counter << std::endl;
return 0;
}
std::unique_lock
std::unique_lock
은 std::lock_guard
보다 더 유연한 동기화 도구로, 뮤텍스를 잠금/해제하는 시점을 제어할 수 있습니다.
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void printMessage(const std::string& msg) {
std::unique_lock<std::mutex> lock(mtx);
std::cout << msg << std::endl;
lock.unlock(); // 뮤텍스 해제
// 다른 작업 수행
lock.lock(); // 뮤텍스 다시 잠금
std::cout << "Finished: " << msg << std::endl;
}
int main() {
std::thread t1(printMessage, "Hello from thread 1");
std::thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
std::condition_variable
조건 변수는 특정 조건이 충족될 때까지 스레드를 대기 상태로 유지하는 동기화 도구입니다. 조건 변수는 std::mutex
와 함께 사용됩니다.
예제 코드
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void printMessage() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return ready; }); // ready가 true가 될 때까지 대기
std::cout << "Hello from thread!" << std::endl;
}
void setReady() {
std::this_thread::sleep_for(std::chrono::seconds(1)); // 잠시 대기
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
}
cv.notify_one(); // 대기 중인 스레드를 깨움
}
int main() {
std::thread t1(printMessage);
std::thread t2(setReady);
t1.join();
t2.join();
return 0;
}
실습 문제
문제 1: std::thread와 동기화 기법 사용하기
다음 코드에서 std::thread
와 동기화 기법을 사용하여 두 개의 스레드가 안전하게 공유 자원에 접근하도록 구현하세요.
main.cpp
#include <iostream>
#include <thread>
#include <mutex>
int counter = 0;
std::mutex mtx;
void incrementCounter() {
for (int i = 0; i < 100000; ++i) {
counter++;
}
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << "Final counter value: " << counter << std::endl;
return 0;
}
해답:
main.cpp (동기화 추가)
#include <iostream>
#include <thread>
#include <mutex>
int counter = 0;
std::mutex mtx;
void incrementCounter() {
for (int i = 0; i < 100000; ++i) {
std::lock_guard<std::mutex> lock(mtx); // 뮤텍스 잠금
counter++;
}
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << "Final counter value: " << counter << std::endl;
return 0;
}
이제 열여섯 번째 날의 학습을 마쳤습니다. std::thread
와 동기화 기법을 이해하고, 이를 사용하여 안전한 멀티스레딩을 구현하는 방법을 학습했습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "병렬 알고리즘과 std::async"에 대해 학습하겠습니다.
'-----ETC----- > C++ 성능 최적화 및 고급 테크닉 시리즈' 카테고리의 다른 글
[C++ 성능 최적화 및 고급 테크닉] Day 18: 고급 멀티스레딩 기법 (락 프리 프로그래밍) (0) | 2024.08.01 |
---|---|
[C++ 성능 최적화 및 고급 테크닉] Day 19: 병렬 STL 사용법 (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 17: 병렬 알고리즘과 std::async (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 14: CRTP (Curiously Recurring Template Pattern) 사용법 (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 15: 멀티스레딩의 기본 개념 (0) | 2024.08.01 |