뮤텍스는 여러 스레드의 공유자원을 보호하기 위해 사용되는 클래스이다.
std::mutex
는 상호배타적이며, 비재귀적인 소유권을 가진다.
스레드에서 lock
또는 try_lock
을 호출하면 unlock
이 될 때까지 해당 Mutex의 소유권을 가진다.
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
void worker(int& counter)
{
for (int i = 0; i < 10000; i++)
{
counter += 1;
}
}
int main()
{
int counter = 0;
vector<thread> workers;
for (int i = 0; i < 4;i++)
{
workers.push_back(thread(worker, ref(counter)));
}
for (int i = 0;i < 4;i++)
{
workers[i].join();
}
cout << "Counter 최종 값 : " << counter << endl;
return 0;
}
위 코드를 실행한 결과이다.
최종값이 40000이 나오기를 기대했지만 엉뚱한 값이 나왔음을 알 수 있다.
이는 counter += 1
을 여러 쓰레드가 동시에 수행하게 되면서 문제가 발생한다.
만약 두 쓰레드에서 counter += 1
이 동시에 수행된다면 결과적으론 counter += 2
가 이뤄져야 하는데 최종 결과는 counter += 1
이 된다.
그래서 뮤텍스를 적용시키는데, 코드에 적용시키면 아래와 같다.
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
using namespace std;
void worker(int& counter, mutex& m)
{
for (int i = 0; i < 10000; i++)
{
m.lock();
counter += 1;
m.unlock();
}
}
int main()
{
int counter = 0;
mutex m;
vector<thread> workers;
for (int i = 0; i < 4;i++)
{
workers.push_back(thread(worker, ref(counter), ref(m)));
}
for (int i = 0;i < 4;i++)
{
workers[i].join();
}
cout << "Counter 최종 값 : " << counter << endl;
return 0;
}