简体   繁体   中英

C++ Is it safe to modify a int64_t when reading it from another thread?

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?

No, it's undefined behavior.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM