答案:不是。
先看个例子:
#include <iostream>
#include <atomic>
#include <thread>
using namespace std;
static atomic<int> atomicvalue(0);
static int value = 0;
constexpr int count = 10000;
void increase() {
for (auto i = 0; i < count; i ++) {
++atomicvalue;
++value;
}
}
void decrease() {
for (auto i = 0; i < count; i ++) {
--atomicvalue;
--value;
}
}
int main() {
thread incr(increase);
thread decr(decrease);
incr.join();
decr.join();
// when thread all done
// atomic value will be zero
// non-atomic value may not be zero
cout << "atomic value:" << atomicvalue << endl;
cout << "non-atomic value:" << value << endl;
return 0;
}
atomic value 一定是 0,但 non-atomic 的结果是看 cpu 心情的:
atomic value:0
non-atomic value:269
atomic value:0
non-atomic value:-2027
我们知道 i++ 是:先复制,再自增,再返回复制结果;++i 是只自增。但这些都是在 c++ 层面的逻辑。
我们把一段简单的代码汇编以下看看结果:
int main() {
int i = 1;
++i;
return 0;
}
汇编结果:
.file "mm.cpp"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $1, -4(%rbp)
addl $1, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
.section .note.GNU-stack,"",@progbits
这三行是 ++i 的汇编结果:
movl $1, -4(%rbp)
addl $1, -4(%rbp)
movl $0, %eax
所以 ++i 不是原子操作,非线程安全。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。