반응형
1. 설명
- 원자적으로 처리할 변수에 대해 정의한다.
- 쓰레드 동작시 공유 변수의 동시성(Concurrency) 문제에 대해 해결해 준다.
2. 문제 상황
- 아래의 코드를 실행해보면 전역 변수 num을 2개의 쓰레드가 각각 더하거나 뺀다.
- 더하거나 빼는 과정에 문맥교환(Context Switching)이 일어나면 연산이 완료되기 전에 제어권을 빼앗길 수 있다.
- 더하거나 빼는 연산을 원자적으로 처리하기 위해 atomic 변수로 선언이 필요하다.
#include <iostream>
#include <thread>
int num{0};
void ThreadHandler(const bool isAdd)
{
for (int i=0; i<1000000; i++)
{
if (isAdd) num++;
else num--;
}
std::cout << "num=" << num << std::endl;
}
int main()
{
std::jthread thr1{ThreadHandler, true};
std::jthread thr2{ThreadHandler, false};
return 0;
}
3. 사용법
#include <atomic>
std::atomic< var-type > var;
(1) 인자
1-1) var-type : 변수나 객체의 타입을 지정
4. 사용 예제
- 위에서 문제가 됐던 num 변수의 타입을 std::atomic<int>로 변경해 준다.
- 이제 num 변수의 원자성이 보장되기 때문에 마지막 출력값은 항상 0이 된다.
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<int> num{0}; //atomic 변수 선언
void ThreadHandler(const bool isAdd)
{
for (int i=0; i<1000000; i++)
{
if (isAdd) num.fetch_add(1); //atomic 값을 증가 (num++ 사용가능)
else num.fetch_sub(1); //atomic 값을 감소 (num-- 사용가능)
}
std::cout << "num=" << num.load() << std::endl; //atomic 값을 출력
}
int main()
{
num.store(0); //atomic 변수 초기화
std::jthread thr1{ThreadHandler, true};
std::jthread thr2{ThreadHandler, false};
return 0;
}
반응형
'Programming Language > C++11' 카테고리의 다른 글
[c++11] std::tuple - 두 개 이상의 변수나 객체를 한번에 전달 (0) | 2024.07.02 |
---|---|
[c++11] std::pair - 두 개의 변수나 객체를 한번에 전달 (0) | 2024.07.02 |
[c++11] Lambda Function (람다 함수) - 익명 함수 (10) | 2024.06.26 |
[c++11] std::function - 함수 포인터를 대체하는 키워드 (9) | 2024.06.25 |
[c++11] Smart Pointer (std::unique_ptr, std::shared_ptr) (21) | 2024.06.24 |