-
C++ 멀티스레딩 프로그래밍과 동기화 기법c++ 2025. 2. 3. 21:10728x90
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'c++' 카테고리의 다른 글
Modern C++ (0) 2025.02.06 C++ 네트워크 프로그래밍과 소켓 통신 (0) 2025.02.04 C++ 표준 템플릿 라이브러리(STL)와 스마트 포인터 (0) 2025.02.03 C++ 객체 지향 프로그래밍: 연산자 오버로딩과 템플릿 (0) 2025.02.02 C++ 객체 지향 프로그래밍: 상속과 다형성 (0) 2025.02.01