멀티스레딩 (Multithreading)
멀티스레딩은 하나의 프로그램이 동시에 여러 작업을 수행할 수 있도록 하는 기능입니다. C++11부터 표준 라이브러리는 멀티스레딩을 지원하는 다양한 기능을 제공합니다. 주요 클래스와 함수로는 thread
, mutex
, lock_guard
, unique_lock
등이 있습니다.
1. 스레드 (Thread)
스레드는 프로그램의 실행 단위를 나타냅니다. std::thread
클래스를 사용하여 스레드를 생성할 수 있습니다.
1.1 스레드 생성
#include <iostream>
#include <thread>
using namespace std;
void printMessage(const string& message) {
cout << message << endl;
}
int main() {
thread t1(printMessage, "Hello from thread 1");
thread t2(printMessage, "Hello from thread 2");
t1.join(); // 스레드 t1이 종료될 때까지 대기
t2.join(); // 스레드 t2가 종료될 때까지 대기
return 0;
}
2. 뮤텍스 (Mutex)
뮤텍스는 상호 배제를 제공하여, 여러 스레드가 동시에 공유 자원에 접근하는 것을 방지합니다. std::mutex
클래스를 사용하여 뮤텍스를 생성할 수 있습니다.
2.1 뮤텍스 사용
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx;
void printMessage(const string& message) {
lock_guard<mutex> guard(mtx);
cout << message << endl;
}
int main() {
thread t1(printMessage, "Hello from thread 1");
thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
3. lock_guard와 unique_lock
lock_guard
와 unique_lock
은 RAII 스타일의 뮤텍스 잠금을 제공합니다. lock_guard
는 간단한 경우에 사용하고, unique_lock
은 더 복잡한 잠금 관리가 필요할 때 사용합니다.
3.1 lock_guard 사용
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx;
void printMessage(const string& message) {
lock_guard<mutex> guard(mtx);
cout << message << endl;
}
int main() {
thread t1(printMessage, "Hello from thread 1");
thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
3.2 unique_lock 사용
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx;
void printMessage(const string& message) {
unique_lock<mutex> lock(mtx);
cout << message << endl;
lock.unlock();
// 다른 작업 수행 가능
lock.lock();
// 다시 잠금 가능
}
int main() {
thread t1(printMessage, "Hello from thread 1");
thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
예제 문제
문제 1: 스레드를 사용하여 두 개의 함수를 동시에 실행
두 개의 함수를 각각 별도의 스레드에서 실행하고, 두 스레드가 모두 종료된 후 메인 함수가 종료되도록 프로그램을 작성하세요.
해설:
#include <iostream>
#include <thread>
using namespace std;
void function1() {
cout << "Function 1 is running" << endl;
}
void function2() {
cout << "Function 2 is running" << endl;
}
int main() {
thread t1(function1);
thread t2(function2);
t1.join();
t2.join();
cout << "Both threads have finished" << endl;
return 0;
}
이 프로그램은 두 개의 함수를 각각 별도의 스레드에서 실행하고, 두 스레드가 모두 종료된 후 메인 함수가 종료됩니다.
문제 2: 뮤텍스를 사용하여 공유 자원의 동기화
두 개의 스레드가 동일한 공유 자원에 접근할 때 뮤텍스를 사용하여 동기화하는 프로그램을 작성하세요. 공유 자원은 정수 변수로 하고, 두 스레드가 번갈아가며 값을 증가시키도록 하세요.
해설:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int sharedCounter = 0;
mutex mtx;
void incrementCounter() {
for (int i = 0; i < 100; ++i) {
lock_guard<mutex> guard(mtx);
++sharedCounter;
}
}
int main() {
thread t1(incrementCounter);
thread t2(incrementCounter);
t1.join();
t2.join();
cout << "Final counter value: " << sharedCounter << endl;
return 0;
}
이 프로그램은 두 개의 스레드가 동일한 공유 자원에 접근할 때 뮤텍스를 사용하여 동기화합니다.
문제 3: unique_lock을 사용하여 복잡한 잠금 관리
unique_lock
을 사용하여 복잡한 잠금 관리가 필요한 상황을 시뮬레이션하는 프로그램을 작성하세요. 두 개의 스레드가 번갈아가며 공유 자원의 값을 증가시키고, 값을 출력하도록 하세요.
해설:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int sharedCounter = 0;
mutex mtx;
void incrementAndPrint() {
for (int i = 0; i < 100; ++i) {
unique_lock<mutex> lock(mtx);
++sharedCounter;
cout << "Counter value: " << sharedCounter << endl;
lock.unlock();
this_thread::sleep_for(chrono::milliseconds(10)); // 다른 작업 수행 시뮬레이션
lock.lock();
// 다시 잠금 후 다른 작업 수행 가능
}
}
int main() {
thread t1(incrementAndPrint);
thread t2(incrementAndPrint);
t1.join();
t2.join();
cout << "Final counter value: " << sharedCounter << endl;
return 0;
}
이 프로그램은 unique_lock
을 사용하여 복잡한 잠금 관리를 시뮬레이션합니다.
다음 단계
26일차의 목표는 C++의 멀티스레딩과 동기화에 대해 학습하는 것이었습니다. 다음 날부터는 최신 C++ 표준(C++11, C++14, C++17, C++20) 기능 소개에 대해 다룰 것입니다.
내일은 "최신 C++ 표준(C++11, C++14, C++17, C++20) 기능 소개"에 대해 다룰 예정입니다. 질문이나 피드백이 있으면 댓글로 남겨 주세요!
'-----ETC----- > C++ 마스터 시리즈' 카테고리의 다른 글
[C++ 마스터] Day 28: 최적화 기법과 코드 프로파일링 (0) | 2024.08.01 |
---|---|
[C++ 마스터] Day 29: C++에서의 디자인 패턴 (0) | 2024.08.01 |
[C++ 마스터] Day 27: 최신 C++ 표준 (C++11, C++14, C++17, C++20) 기능 소개 (0) | 2024.08.01 |
[C++ 마스터] Day 24: 프로젝트 - 간단한 콘솔 게임 만들기 (2) (0) | 2024.08.01 |
[C++ 마스터]Day 25: 스마트 포인터 (unique_ptr, shared_ptr) (0) | 2024.08.01 |