1. Mutex
1.1 Race Condition
- 여러 쓰레드에서 동시에 실행시켰으므로 한 번에 한 쓰레드에서만 코드를 실행시키는 방법
- Race Condition을 해결할 수 있는 Mutex 사용
1.2 Mutex
- 상호 배제(mutual exclusion)
- Lock
- 한 번에 한 쓰레드에서만 mutex의 사용 권한을 갖는 것
- mutex를 소유한 쓰레드가 unlock을 통해 mutex를 반환할 때까지 무한정 대기상태
- UnLock
- 위에서 말했듯이 mutex를 반환할 때까지 무한정 대기상태
- unlock을 하지 않는 경우 본인도 본인을 기다리고 다른 쓰레드들도 unlock할때까지 기다리게 됨
- 아무도 연산을 진행X → 데드락(deadlock) 상태
void worker(int& counter, std::mutex& m)
{
for (int i = 0; i < 10000; i++)
{
m.lock();
counter++;
m.unlock();
}
}
int main()
{
vector<std::thread> worker;
std::mutex m;
int counter = 0;
// ref - 레퍼런스로 전달하려면 ref 함수로 감싸야 함
for (int i = 0; i < 2; i++) worker.push_back(std::thread(worker, std::ref(counter), std::ref(m)));
for (int i = 0; i < 2; i++) worker[i].join();
cout << counter << endl;
}
- lock과 unlock 사이에 한 쓰레드만이 유일하게 실행할 수 있는 코드 부분을 임계 영역(Critical section)
1.3 Lock Guard
- 메모르 할당 및 해제하는 것 처럼 Mutex도 사용을 하면 해제를 해야함
- DeadLock이 일어나지 않도록 처리
void worker(int& counter, std::mutex& m)
{
for (int i = 0; i < 10000; i++)
{
// lock guard 생성 동시에 lock 생성
std::lock_guard<std::mutex> lock(m);
counter++;
// 종료시 자동적으로 unlock 실행
}
}
int main()
{
vector<std::thread> workers;
std::mutex m;
int counter = 0;
// ref - 레퍼런스로 전달하려면 ref 함수로 감싸야 함
for (int i = 0; i < 2; i++) workers.push_back(std::thread(worker, std::ref(counter), std::ref(m)));
for (int i = 0; i < 2; i++) workers[i].join();
cout << counter << endl;
}
'Create Game > [Window API] Game Client & Game Server' 카테고리의 다른 글
[SERVER] Producer & Consumer (0) | 2023.01.03 |
---|---|
[SERVER] Dead Lock (0) | 2023.01.03 |
[SERVER] Race Condition (0) | 2023.01.03 |
[SERVER] Thread (0) | 2023.01.03 |
[Game Client] 9 - UI (0) | 2022.12.31 |