Back to TILs

C++ atomic 01

Date: 2021-02-22Last modified: 2023-03-16

Table of contents

#include <atomic>
#include <iostream>
#include <mutex>
#include <numeric>
#include <thread>

using namespace std;

// std::atomic<int> x{0};
// ++x;           // atomic pre-increment
// x++;           // atomic post-incrment
// x += 1;        // atomic increment
// x |= 2;        // atomic bit set
// int y = x * 2; // atomic read of x
// x = y + 1;     // atomic write
// x = x + 1;     // atomic read followed by atomic write
// x = x * 2;     // atomic read followed by atomic write
// ---- x *= 2;   // NÃO EXISTE MULTIPLICAÇÃO ATOMICA

// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
// usar construtor em vez de std::atomic<unsigned long> sum1 = 0
atomic<unsigned long> sum1( 0 );
void                  doWork1( size_t N, unsigned long *a )
{
  for( size_t i = 0; i < N; ++i ) {
    sum1 += a[i];
  }
}

// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
unsigned long sum2( 0 );
mutex         M;
void          doWork2( size_t N, unsigned long *a )
{
  unsigned long s = 0;
  for( size_t i = 0; i < N; ++i ) {
    s += a[i];
  }
  lock_guard<mutex> L( M );
  sum2 += s;
}

// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
int main()
{
  constexpr size_t        N = 10000;
  array<unsigned long, N> data;
  iota( data.begin(), data.end(), 1000 );

  cout << "Sum1: " << sum1 << endl;
  cout << "Sum2: " << sum2 << endl;

  thread t1( doWork1, N, data.data() );
  thread t2( doWork2, N, data.data() );

  t1.join();
  t2.join();

  cout << "Sum1: " << sum1 << endl;
  cout << "Sum2: " << sum2 << endl;
}

Possible output

Sum1: 0
Sum2: 0
Sum1: 59995000
Sum2: 59995000

References