Are C++ Reads and Writes of an int Atomic?

2019-01-03 02:28发布

I have two threads, one updating an int and one reading it. This is a statistic value where the order of the reads and writes is irrelevant.

My question is, do I need to synchronize access to this multi-byte value anyway? Or, put another way, can part of the write be complete and get interrupted, and then the read happen.

For example, think of a value = 0x0000FFFF that gets incremented value of 0x00010000.

Is there a time where the value looks like 0x0001FFFF that I should be worried about? Certainly the larger the type, the more possible something like this to happen.

I've always synchronized these types of accesses, but was curious what the community thinks.

15条回答
beautiful°
2楼-- · 2019-01-03 02:47

tc, I think the moment you use a constant ( like 6) , the instruction wouldn't be completed in one machine cycle. Try to see the instruction set of x+=6 as compared to x++

查看更多
家丑人穷心不美
3楼-- · 2019-01-03 02:52

The only portable way is to use the sig_atomic_t type defined in signal.h header for your compiler. In most C and C++ implementations, that is an int. Then declare your variable as "volatile sig_atomic_t."

查看更多
甜甜的少女心
4楼-- · 2019-01-03 02:56

Some people think that ++c is atomic, but have a eye on the assembly generated. For example with 'gcc -S' :

movl    cpt.1586(%rip), %eax
addl    $1, %eax
movl    %eax, cpt.1586(%rip)

To increment an int, the compiler first load it into a register, and stores it back into the memory. This is not atomic.

查看更多
爷的心禁止访问
5楼-- · 2019-01-03 02:57

At first one might think that reads and writes of the native machine size are atomic but there are a number of issues to deal with including cache coherency between processors/cores. Use atomic operations like Interlocked* on Windows and the equivalent on Linux. C++0x will have an "atomic" template to wrap these in a nice and cross-platform interface. For now if you are using a platform abstraction layer it may provide these functions. ACE does, see the class template ACE_Atomic_Op.

查看更多
冷血范
6楼-- · 2019-01-03 03:00

You must synchronize, but on certain architectures there are efficient ways to do it.

Best is to use subroutines (perhaps masked behind macros) so that you can conditionally replace implementations with platform-specific ones.

The Linux kernel already has some of this code.

查看更多
劳资没心,怎么记你
7楼-- · 2019-01-03 03:00

Definitively NO ! That answer from our highest C++ authority, M. Boost:
Operations on "ordinary" variables are not guaranteed to be atomic.

查看更多
登录 后发表回答