1. 程式人生 > >2012-08-22 Linux下原子操作

2012-08-22 Linux下原子操作

今天在開發的過程中遇到這麼一個情形,有兩個執行緒分別對一個 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))    博主所有文章已轉自私人部落格Joe 的個人部落格,謝謝關注!