线程同步与原子操作

volatile

  • volatile使得代码每次在读写volatile变量时都需要从内存读写,而不能使用寄存器中缓存的值。并且也禁止编译器对volatible做编译优化。volatile本身并不是用于线程同步,也不保证原子读写(例如volatile a++这种需要几个指令才能完成的操作)。volatile主要用于access to memory mapped devices和variables in signal handlers and between setjmp and longjmp。C++标准禁止编译器reorder同一个线程内的volatile变量的读写,但不同线程则没有限制。non-volatile变量则有可能发生reorder( Stay away from Volatile in threaded code? )。而根据 为什么volatile++不是原子性的? 中的说法,volatile的读操作后会插入LoadLoad和LoadStore屏障,避免volatile读操作与后面的普通读写发生reorder。而volatile的写操作前会插入StoreLoad和StoreStore屏障,避免volatile写操作与后面的普通读写发生reorder。
  • volatile跟const一样属于变量修饰符,因此也和const一样必须弄清楚修饰的是指针还是变量自身(或者甚至是第几级指针)。例如 uchar * volatile reg; 说明指针reg本身是volatile的,而 volatile uchar *reg; 说明*reg(也就是reg指向的变量)是volatile的。而且volatile也可以和const同时使用。
  • volatile陷阱 一文中有提到几种volatile的陷阱和误用。
  • “Volatile” can be harmful… 中提到可以将函数参数标记为volatile避免编译器优化,从而便于debug。

临界区块(Critical section)

内存屏障

  • 首先要明白的一点,reorder不仅可以发生在编译时,也可以发生在运行时。CPU流水线也可以重排某些指令顺序。所以即使是同一段编译好的程序,不同的CPU内核也可能执行不同的指令顺序。

本文地址: http://xnerv.wang/thread-synchronization-and-atomic-operation/

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章