为什么需要原子性操作?
我们考虑这样一种场景,两个线程对同一个变量同时x++操作。
x++ 在计算机的步骤:从内存中读取x的值到寄存器中,对寄存器加1,再把新值写回x所处的内存地址。
假设有如下时序图:
两个线程运行结束后,x等于11,正确应该是12,那要得出正确的结果,有两个方法:
第一种是锁:在X++ 之前加一把锁,加完解锁。这样就可以保证在同一时刻只有一个线程进入临界区域,对X进行读的操作,写的操作,当一个线程进入这个临界区域的时候,其他线程就不能访问这个临界区的资源,只能等到占用的线程unlook 的时候才能进入。多个线程访问资源的时候势必会发生锁竞争。锁竞争是高性能服务器四大杀手之一,我们应该尽可能的减少锁的使用。原子性操作可以实现这一目标。
第二种原子操作:原子性操作可以把X++的3步骤看成一个整体。现代的CPU都提供了原子性操作的相关指令。
这些是GCC 提供的原子性操作,当然前提是CPU支持原子性操作的指令。
// 原子自增操作
type __sync_fetch_and_add (type *ptr, type value)
// 原子比较和交换(设置)操作
type __sync_val_compare_and_swap (type *ptr, type oldval type newval)
boo