[英]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.