오보에블로그
[C++] 멀티 스레드 와 mutex 본문
728x90
멀티 스레드란?
- 멀티 스레드란, 하나의 프로세스 안의 여러개의 스레드를 병렬적으로 실행시키는 것을 의미한다.
- 멀티 프로세스와 다르게 프로세스 안의 자원을 공유할 수 있어서, 컨텍스트 스위치 비용이 적다는 장점이 있다.
- 하지만, 여러 스레드에서 동시 자원을 사용할 때 문제가 발생할 수 있다. 아래의 코드 예시를 확인해보자.
#include <thread>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int counter = 0;
void func()
{
for (int i = 0; i < 100000; i++)
counter += 1;
}
int main() {
vector<thread> ts;
// counter에 1씩 100000번 더하는 스레드 5개 생성
for (int i = 0; i < 5; i++)
ts.push_back(thread(func));
for (int i = 0; i < 5; i++) {
ts[i].join();
}
cout << counter;
return 0;
}
- 아래의 출력물은
counter
가500000
이 나오는 게 이상적이지만, 그것보다 작은 수가 출력될 것이다. - 그 이유는 멀티 스레드로 인해 공유 자원으로 사용하는
counter
의 연산과정이 제대로 이루어지지 않고 있기 때문이다. counter += 1
부분에 중단점을 걸어서 실행시켰을 때 디스어셈블리 코드를 펼쳐보면 아래와 같다.
- 이를 풀어서 보면 다음과 같다.
eax
는 64비트 레지스터rax
의 절반크기를 의미, 하지만 여기서 중요하지는 않다.
mov eax, dword ptr [counter] ; 1. counter의 값을 eax에 복사한다.
inc eax ; 2. eax을 1 증가시킨다.
mov dword ptr [counter], eax ; 3. eax을 counter 값에 복사한다.
- 코드 상으로는 한줄이지만, 컴퓨터는 세가지의 연산 과정을 거쳐서
counter += 1
를 수행하고 있었던 것이었다..! 만약에 그렇다면,, 현재counter
가0
인 상태에서 2개의 스레드가 해당 어셈블리 과정을 진행한다고 할 때 - A , B 스레드 모두 1 번 과정을 진행하고 2로 넘어가는 중이라고하자.
- 1번 과정 진행 시
A
,B
스레드 상에서 모두eax
에0
이 할당 되고, 각각 1씩 증가 시키고, 결과적으로counter
에는 1이 복사될 것이다.
- 우리는 이를 해결하기 위해서
counter
와 같은 자원에 한번에 하나의 스레드만 접근할 수 있도록 하고 싶다. - C++ 에서는 이를 위해서
mutex
라는 객체를 사용할 수 있다.
mutex
- mutex 레퍼런스
void lock()
: 해당mutex
를 잠근다. 이미 다른 스레드에서 잠그었다면 잠글 수 있을 때까지 다음 코드를 실행시키지 않는다.]bool try_lock()
: 해당mutex
를 잠근다. 성공했다면true
, 이미 다른 스레드에서 잠그었다면false
리턴void unlock()
: 해당mutex
잠금을 해제한다.- 아래와 같이 이전 코드에
mutex
을 추가해서 올바른 출력 결과를 만들 수 있다.
#include <thread>
#include <iostream>
#include <vector>
#include <algorithm>
#include <mutex>
using namespace std;
mutex mtx; // mutex 객체 생성
int counter = 0;
void func()
{
mtx.lock(); // 잠금
for (int i = 0; i < 100000; i++)
counter += 1;
mtx.unlock(); // 해제
}
int main() {
vector<thread> ts;
for (int i = 0; i < 5; i++)
ts.push_back(thread(func));
for (int i = 0; i < 5; i++) {
ts[i].join();
}
cout << counter;
return 0;
}
728x90
'C++ & C# > C++' 카테고리의 다른 글
dll 생성 예제 (0) | 2022.11.06 |
---|---|
[C++] Modern C++ 버전 별 문법 정리 (0) | 2022.05.01 |
[C++] std::this_thread 사용법 (0) | 2022.02.24 |
[C++] std::thread 사용법 (0) | 2022.02.24 |
[C++Docs] 타입 최대 최소 define 상수 라이브러리 (0) | 2022.01.10 |