书中举了一个很简单的例子:
int global_x = 0; // 两个线程共享的全局变量.
Thread1: // 线程 1 的定义 Thread2: // 线程 2 的定义
lock(); lock();
global_x++; global_x++;
unlock(); unlock();
看上去,因为线程 1 和线程 2 在访问 global_x
时都使用了 lock()
和 unlock()
保护,因此 global_x++
的行为不会被并发破坏,所以在线程 1 和线程 2 结束之后,global_x 的值似乎一定是 2。但其实,这么理所当然的猜测有可能是错误的。解释如下:
出现这样的问题,是因为编译器为了提高global_x
的访问速度,将global_x
的值放到了某个寄存器里,这就导致了所谓过度优化的问题。
书中给出的为了阻止过度优化的方法是使用 volatile
关键字。(注:这里的 volatile 仅指 C/C++的关键字,不要和 java 中的搞混)
我的理解是volatile
从来不是多线程中需要的,靠操作系统提供的同步原语应该就足够了。
相关链接:
pthread locks implement memory barriers that will ensure that cache effects are made visible to other threads. You don't need volatile to properly deal with the shared variable i if the accesses to the shared variable are protected by pthread mutexes.
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.