Program Language/C & C++

[C++] atomic

야곰야곰+책벌레 2021. 10. 1. 10:56
728x90
반응형

  std::atomic은 원자성을 보존해주기 위해 사용된다. 다시 말하자면 mutex 없이 두 개의 스레드가 동시에 접근해도 data race 문제가 발생하지 않는다. 또한 std::atomic을 기록하는 라인이 수행될 때는 이전에 나타난 라인들이 수행되어서는 안 된다.

 

  std::atomic은 복사와 이동 연산을 지원하지 않는다. 원자성을 보존해야 하기 때문이다. 다행히 복사하는 방법은 있다.

atd::atomic<int> y(x.load());
y.store(x.load());

 

  mutex를 통한 전역 변수 동기화에서는 dead lock에 빠질 수 있다. 그래서 atomic을 이용하여 lock, unlock을 사용하지 않고 값을 증가시키거나 감소시킬 수 있는 기능이 C++11부터 제공되고 있다.

atomic : atomic 변수를 선언하는 데이터형
fetch_add : 값을 증가시키는 함수
fetch_sub : 값을 감소시키는 함수

  atomic은 설정 초기에만 값을 대입할 수 있다. 그 외에는 증가, 감소의 역할만 수행한다. 그것은 atomic만의 독특한 기능 때문이다. atomic이 동작 중에는 다른 작업 수행이 멈춘다. 그래서 성능 저하를 피하기 위해서 값의 증감 및 AND/OR/XOR 등의 비트 연산을 사용한다. 

#include <atomic>
using namespace std;

int main()
{
	atomic<int> atomicInt = 1;
	atomicInt.fetch_add(1);
	cout << atomicInt << endl;
	atomicInt.fetch_sub(2);
	cout << atomicInt << endl;

	return 0;
}


atd::stomic<T>::store(T desired, std::memory_order order)

void store(T desired, std::memory_order order = std::memory_order_seq_cst) noexcept;
void store(T desired, std::memory_order order = std::memory_order_seq_cst) volatile noexcept;

// Parameters
// desired : the value to store into the atomic variable
// order : memory order constraints to enfore

  현재의 값을 원하는 값으로 원자적으로 바꾼다. 메모리는 순서 값에 따라 영향을 받는다. order는 std::memory_order_relaxed, std::memory_order_release 또는 std::memory_order_seq_cst 중 하나여야 한다. 그렇지 않으면 동작은 정의 되지 않는다.

 

// until C++20
typedef enum memory_order
{
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst
} memory_order;

// since C++20
enum class memory_order : 
{
    relaxed,
    consume,
    acquire,
    release,
    acq_rel,
    seq_cst
};
inline constexpr memory_order memory_order_relaxed = memory_order::relaxed;
inline constexpr memory_order memory_order_consume = memory_order::consume;
inline constexpr memory_order memory_order_acquire = memory_order::acquire;
inline constexpr memory_order memory_order_release = memory_order::release;
inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel;
inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst;

 

728x90
반응형