c++
C++ 멀티스레딩 프로그래밍과 동기화 기법
난개발자
2025. 2. 3. 21:10
728x90
1. 멀티스레딩(Multithreading)이란?
멀티스레딩은 하나의 프로그램이 동시에 여러 작업을 수행할 수 있게 해주는 기술입니다. C++에서는 thread 라이브러리를 통해 멀티스레딩을 구현할 수 있습니다.
(1) 스레드의 기본 개념
- 스레드(Thread): 프로세스 내에서 실행되는 가장 작은 단위
- 멀티스레딩을 통해 병렬 처리가 가능하여 성능을 향상시킬 수 있습니다.
2. C++에서 스레드 사용하기
(1) 기본 스레드 생성 및 실행
#include <iostream>
#include <thread>
using namespace std;
void printMessage() {
cout << "스레드에서 실행 중입니다." << endl;
}
int main() {
// 스레드 생성
thread t(printMessage);
// 메인 스레드에서 실행
cout << "메인 스레드에서 실행 중입니다." << endl;
// 스레드 종료 대기
t.join();
return 0;
}
출력 결과:
메인 스레드에서 실행 중입니다.
스레드에서 실행 중입니다.
(2) 인자 전달 스레드
스레드 함수에 인자를 전달할 수 있습니다.
#include <iostream>
#include <thread>
using namespace std;
void printNumber(int num) {
cout << "숫자: " << num << endl;
}
int main() {
thread t(printNumber, 42);
t.join();
return 0;
}
출력 결과:
숫자: 42
3. 동기화(Synchronization)란?
동기화는 여러 스레드가 공유 자원에 동시에 접근할 때 발생할 수 있는 문제(데이터 충돌)를 방지하기 위한 기술입니다.
(1) 데이터 경쟁(Race Condition)
- 두 개 이상의 스레드가 동일한 자원에 접근할 때 발생하는 예측 불가능한 결과
- 이를 방지하기 위해 **뮤텍스(Mutex)**를 사용합니다.
4. 뮤텍스(Mutex) 사용하기
(1) 기본 뮤텍스 사용법
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx; // 뮤텍스 객체 생성
void printSafeMessage(const string& message) {
mtx.lock();
cout << message << endl;
mtx.unlock();
}
int main() {
thread t1(printSafeMessage, "스레드 1 실행 중");
thread t2(printSafeMessage, "스레드 2 실행 중");
t1.join();
t2.join();
return 0;
}
출력 결과:
스레드 1 실행 중
스레드 2 실행 중
(2) lock_guard를 활용한 뮤텍스 관리
lock_guard는 뮤텍스를 자동으로 관리하여 lock과 unlock을 명시적으로 작성할 필요가 없습니다.
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx;
void printSafeMessage(const string& message) {
lock_guard<mutex> lock(mtx); // 자동으로 뮤텍스 잠금 및 해제
cout << message << endl;
}
int main() {
thread t1(printSafeMessage, "스레드 1 실행 중");
thread t2(printSafeMessage, "스레드 2 실행 중");
t1.join();
t2.join();
return 0;
}
5. 조건 변수(Condition Variable)
조건 변수는 스레드 간의 통신을 가능하게 하며, 특정 조건이 충족될 때까지 스레드를 대기 상태로 유지합니다.
(1) 조건 변수 사용 예제
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
mutex mtx;
condition_variable cv;
bool ready = false;
void printMessage() {
unique_lock<mutex> lock(mtx);
cv.wait(lock, [] { return ready; }); // ready가 true가 될 때까지 대기
cout << "스레드가 실행되었습니다." << endl;
}
int main() {
thread t(printMessage);
this_thread::sleep_for(chrono::seconds(2)); // 2초 대기
{
lock_guard<mutex> lock(mtx);
ready = true;
}
cv.notify_one(); // 대기 중인 스레드 깨우기
t.join();
return 0;
}
출력 결과:
스레드가 실행되었습니다.
6. 멀티스레딩 실전 예제: 병렬 합계 계산
멀티스레딩을 활용하여 배열의 합계를 병렬로 계산하는 예제입니다.
#include <iostream>
#include <vector>
#include <thread>
using namespace std;
void partialSum(const vector<int>& data, int start, int end, int& result) {
result = 0;
for (int i = start; i < end; ++i) {
result += data[i];
}
}
int main() {
vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int result1 = 0, result2 = 0;
// 두 개의 스레드를 사용하여 배열을 나누어 합계 계산
thread t1(partialSum, cref(data), 0, data.size() / 2, ref(result1));
thread t2(partialSum, cref(data), data.size() / 2, data.size(), ref(result2));
t1.join();
t2.join();
cout << "총 합계: " << result1 + result2 << endl;
return 0;
}
출력 결과:
총 합계: 55
728x90