🎮
Atomic
January 05, 2024
원자성
- 각 쓰레드가 임계영역에서 경쟁(경합)할때, 공유자원에 대한 일관성이 보장되지 않는다.
- a++의 경우
- load a
- a + 1
- store a
- 위 과정이 CPU instruction level에서 일어나는데, 이 중간과정에 다른 쓰레드의 instruction이 개입하면 결과의 일관성이 보장되지 않음.
atomic
#include <atomic>
을 통해 통합 원자성 라이브러리를 추가할 수 있다.
int 사용
int sum = 0;
void Add()
{
for(int i = 0 ; i < 100'0000 < i++){
sum++;
}
}
void Sub()
{
for(int i = 0 ; i < 100'0000 < i++){
sum--;
}
}
void main()
{
std::thread t1(Add);
std::thread t2(Sub);
t1.join();
t2.join();
cout << sum << endl;
return 0;
}
실행 결과
-83031
atomic 사용
atomic<int> sum = 0;
void Add()
{
for(int i = 0 ; i < 100'0000 < i++){
sum.fetch_add(1);
}
}
void Sub()
{
for(int i = 0 ; i < 100'0000 < i++){
sum.fetch_sub(1);
}
}
void main()
{
std::thread t1(Add);
std::thread t2(Sub);
t1.join();
t2.join();
cout << sum << endl;
return 0;
}
실행 결과
0
- atomic의 경우, 일반 int와의 구분을 위해
fetch_add()
,fetch_sub()
등과 같이 사용하는 것이 좋다. - 그냥
sum++
을 사용해도 똑같이 동작한다. 내부적으로 오버로딩이 되어있기 때문.