Home > Software engineering >  C Is it safe to modify a int64_t when reading it from another thread?
C Is it safe to modify a int64_t when reading it from another thread?

Time:07-26

I have 2 threads, A and B. Thread A want to let B know how many records of data it has received. In modern C , we can use Atomic or CAS or Mutex to modify the counter. How ever, neither of them is fast enough for me.

I am thing about, use a int64_t without a lock to share data counter between threads. Only thread A can modify it, other threads can only read it. I don't know whether it is safe to do so.

I know in x86-64 machines, a 64 bit int can be written with one single asm store. So I think it should be safe. And I write the following code to check it. If the method is not safe, cnt will not always increase because we will read wrong values from that 64bit memory.

#include <iostream>
#include <vector>
#include <thread>
using namespace std;

int main() {
    int64_t cnt = 0;
    vector<thread> threadVec;
    for (int i=0; i<10; i  ){
        threadVec.emplace_back(move(thread([&cnt](){
            int64_t prev = 0, tmp = 0;
            while(prev != INT64_MAX){
                tmp = cnt;
                // If it is not safe, tmp will not increase all the time.
                if (tmp < prev) cout << "Error cnt declined" << endl;
                // if (tmp % 1000000 == 0) cout << tmp << endl;
                prev = tmp;
            }
        })));
    }
    this_thread::sleep_for(chrono::seconds(1));
    while(cnt < INT64_MAX) cnt  ;
    for (auto& t : threadVec)
        t.join();
    return 0;
}

So is the idea correct?

CodePudding user response:

No, it's undefined behavior.

Make it a std::atomic<int64_t>, instead. This is what std::atomic is for.

  • Related