[C++]C++11, atomic 샘플 정리

intro

  • InterlockedIncrement(), InterlockedExchange() 등을 대체할수 있는기능, 기존에 이런식으로 코드 작성했었으나, 역시나 C++11에선 정말 편해졌다.
    #if defined ( _WIN32 ) || defined ( _WIN64 )
    ;
    #else
    inline long InterlockedIncrement( volatile long* value )
    {
      int result = 0;
        
      __asm__ __volatile__(
          "lock; xaddl %0, (%1)"
          : "=r" (result)
          : "r" (value), "0" (1)
          : "memory"
          );
        
      return (result + 1);
    }
    inline long InterlockedDecrement( volatile long* value )
    {
      int result = 0;
        
      __asm__ __volatile__(
          "lock; xaddl %0, (%1)"
          : "=r" (result)
          : "r" (value), "0" (-1)
          : "memory"
          );
        
      return (result - 1);
    }
    long InterlockedExchange( volatile long* dest, long value )
    {
      //...
    }
    long InterlockedExchangeAdd( volatile long* dest, long value )
    {
      // http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Atomic-Builtins.html#Atomic-Builtins
      return __sync_fetch_and_add( dest, value );
    }
    long InterlockedCompareExchange( volatile long* dest, long value, long comparand )
    {
      //...
    }
    #endif
    

sample

  • 샘플
    #include <atomic>
    #include <bitset>//bit 값 찍기위해서.
    void test_atomic()
    {
      //값 가져오기 / 대입하기
      std::atomic<int> int_atomic(3);
      int_atomic = 2;//intAtomic에 2 대입
      std::atomic_store(&int_atomic, 4);//intAtomic에 3 대입
      int temp = int_atomic.load();//intAtomic 값 가져오기
      //lock free 인지 확인해보기 (8byte 이하면 atomic보장할듯)
      bool is_lock_free = int_atomic.is_lock_free();
      //atomic 연산, 다양한 방법들..
      int before_value1 = std::atomic_fetch_add(&int_atomic, 5); // int_atomic에 5를 더하기.
      int_atomic++;
      int before_value2 = std::atomic_fetch_sub(&int_atomic, 6); // int_atomic에서 6 빼기.
      int_atomic--;
      //bit연산
      int bit_mask = 0x0a;
      std::cout << std::bitset<4>(int_atomic).to_string() << std::endl;
      std::atomic_fetch_and(&int_atomic, bit_mask); // bit_mask와 and 연산하기.
      std::cout << std::bitset<4>(int_atomic).to_string() << std::endl;
      std::atomic_fetch_or(&int_atomic, bit_mask); // bit_mask와 or 연산하기.
      std::cout << std::bitset<4>(int_atomic).to_string() << std::endl;
      std::atomic_fetch_xor(&int_atomic, bit_mask); // bit_mask와 xor 연산하기.
      std::cout << std::bitset<4>(int_atomic).to_string() << std::endl;
    
      //값 교환
      int temp_value = 100;
      int before_value3 = int_atomic.exchange(temp_value);
      int before_value4 = std::atomic_exchange(&int_atomic, 10);
     
      //VS2013에서는 compare_exchange_weak는 내부적으로 compare_exchange_strong를 호출
      int compare_value = 10;
      int new_value = 30;
      //int_atomic 와 compare_value 값이 같으면 int_atomic에 new_value 대입하는 방법 2가지
      bool isEqual1 = int_atomic.compare_exchange_weak(compare_value, new_value);
      bool ieEqual2 = std::atomic_compare_exchange_weak(&int_atomic, &compare_value, new_value);
    }