今天在思考一个问题:
两个线程访问一个变量A(初始化值是0),一个线程写(准备写的值是0xFF),一个线程读。
在没有锁的情况下,读的线程有没有可能读到的值是0x0F或0xF0。
为什么有这么一个疑问,
因为看到很多代码都是假设这个情况是不可能发生的。
最后在
http://stackoverflow.com/questions/54188/are-c-reads-and-writes-of-an-int-atomic
以及其他地方找到答案。
简单说来跟CPU的数据总线宽度有关,也跟cpu的cache策略有关,
但只要是地址关于总线宽度是对齐的,就能保证上诉的状况不会发生,至少现在x86体系的cpu是这样的。
不过现代的CPU的都能保证这点,不然就弱爆了,谁敢用啊~
也就是保证一个线程不可能看到一个简单类型只写了一半。
intel的开发者文档说明了这一点。
http://www.intel.com/Assets/PDF/manual/253668.pdf
8.1.1 Guaranteed Atomic Operations
The Intel486 processor (and newer processors since) guarantees that the following basic memory operations will always be carried out atomically:
Reading or writing a byte
Reading or writing a word aligned on a 16-bit boundary
Reading or writing a doubleword aligned on a 32-bit boundary
The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically:
Reading or writing a quadword aligned on a 64-bit boundary
16-bit accesses to uncached memory locations that fit within a 32-bit data bus
The P6 family processors (and newer processors since) guarantee that the following additional memory operation will always be carried out atomically:
Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line
现在很多服务器的cpu都是64位的。而且cache line一般也有64Byte。
在比较新款的CPU下,程序员就算没有注意到这个问题,产生BUG的几率也是非常低的。
但它是个BUG!!!
既然有了这个特性,多线程程序又有不少优化点了吧?!