2012-08-22 Linux下原子操作

来源:互联网 发布:面料设计软件下载 编辑:程序博客网 时间:2024/06/16 15:35
今天在开发的过程中遇到这么一个情形,有两个线程分别对一个 map 中的同一变量进行写操作(其中一个是加1操作,另一个是赋零操作),这样会很不安全,通常情况下大家肯定会首先考虑用互斥锁,但是使用线程互斥锁之后性能会下降很多,那么我就选择了原子操作,而原子操作的性能比互斥锁高很多,这里有一篇文章讲到它们之间的性能比较:http://imcc.blogbus.com/logs/179131763.html。
    于是上网找了关于原子操作的资料,所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。然而大部分资料都说原子操作是定义在 include/asm/atomic.h 文件中,但是我在 ubuntu 下搜索这个头文件,根本搜索不到,后来才知道如果没有 atomic.h 头文件的时候,我们也可以使用原子操作,gcc从4.1.2提供了__sync_*系列的built-in函数,用于提供加减和逻辑运算的原子操作。

type __sync_fetch_and_add (type *ptr, type value, ...)
type __sync_fetch_and_sub (type *ptr, type value, ...)
type __sync_fetch_and_or (type *ptr, type value, ...)
type __sync_fetch_and_and (type *ptr, type value, ...)
type __sync_fetch_and_xor (type *ptr, type value, ...)
type __sync_fetch_and_nand (type *ptr, type value, ...)


type __sync_add_and_fetch (type *ptr, type value, ...)
type __sync_sub_and_fetch (type *ptr, type value, ...)
type __sync_or_and_fetch (type *ptr, type value, ...)
type __sync_and_and_fetch (type *ptr, type value, ...)
type __sync_xor_and_fetch (type *ptr, type value, ...)
type __sync_nand_and_fetch (type *ptr, type value, ...)

bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
type __sync_val_compare_and_swap (type 
*ptr, type oldval type newval, ...)
这两个函数提供原子的比较和交换,如果*ptr == oldval,就将newval写入*ptr,
第一个函数在相等并写入的情况下返回true.
第二个函数在返回操作之前的值。 

还有两个函数:

type __sync_lock_test_and_set (type *ptr, type value, ...)
   将*ptr设为value并返回*ptr操作之前的值。

void __sync_lock_release (type *ptr, ...)
     将*ptr置0

于是我们可以用宏来把这些原子操作的函数封装一下:
// The atomic of increment one
#define atomic_inc(x)       __sync_add_and_fetch((x),1)

// The atomic of set to zero            
#define atomic_set_zero(x)  __sync_lock_release(x)

// The atomic of set                 
#define atomic_set(x, y)    __sync_lock_test_and_set((x), (y))