简体   繁体   English

C++ 从另一个线程读取时修改 int64_t 是否安全?

[英]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.我有 2 个线程,A 和 B。线程 A 想让 B 知道它收到了多少条数据记录。 In modern C++, we can use Atomic or CAS or Mutex to modify the counter.在现代 C++ 中,我们可以使用 Atomic 或 CAS 或 Mutex 来修改计数器。 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.我很关心,使用没有锁的 int64_t 在线程之间共享数据计数器。 Only thread A can modify it, other threads can only read it.只有线程 A 可以修改它,其他线程只能读取它。 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 .我知道在 x86-64 机器中,一个 64 位 int 可以用一个 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.如果该方法不安全,cnt 不会总是增加,因为我们将从该 64 位 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.改为std::atomic<int64_t> This is what std::atomic is for.这就是std::atomic的用途。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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