我已经不止一次听到关于volatile int的安全读写方面的谬论了。
最常见的是所谓的volatile int的变量的单写多读操作是多线程安全的。
这个结论很搞笑,因为每当支持这个节论的人给我讲一大堆诸如锁总线,原子指令方面的东西时,(权且当他们都说的全对)我几乎都可以反问他:根据你说的东西可以得到一个结论,volatile int是也多线程写安全的(串行的),volatile int就是原生的信号量。那些搞并发编程的人难道都是吃饱了撑的,搞什么锁来玩的?
好了,谈些基本点,基于c语言标准:
1。volatile的行为是不可移植的(基于编译器,编译器基于cpu)。c语言另外一个不可移植的东西是位域。
2。volatile的行为编译器至少都当作io行为(最低限度的可移植语义,也是最好理解的一种说法,可惜很多人都不明白io行为意味着什么)。
3。volatile变量的读写操作将禁止该操作后的指令在该操作之前执行,之前的指令也不得推后执行。(禁止执行流水线,矢量化等等常见优化,总之跨volatile不能打乱,合并原有的语句来进行优化)
4。c代码编译成汇编之后,什么volatile之内的关键字全没了,只有一堆汇编指令。
5。多线程的语义取决于实现(基于操作系统,操作系统基于cpu,实现代码也都是汇编)。不同的操作系统的多线程实现和调度可能基于不同的原理,和内存管理机制往往关系也不小。这也是win32居然有用户态的critical section这样的同步原语供大家使用,因为它专著x86而linux需要跨cpu,前者就可以直接封装i386汇编来玩,而且恰好win32的线程可以不用进内核态进行系统调用就休眠,唤醒自己(这就是原生多线程系统的好)。
6。c语言的标准和多线程编程没有任何关系,c语言不保证代码在多线程中执行的情况。c的标准出现的可比最早的多线程操作系统win和solary早多了,不可能预测生后事。不同的系统多线程实现更是千奇百怪,很难提炼出一个公有的底层特性。你看看j