鎖 無鎖 多處理器程式設計 2 原子操作

2021-10-06 20:09:58 字數 3082 閱讀 9548

原子操作是不可分割的操作,在執行完畢時它不會被任何事件中斷,原子操作是多數無鎖程式設計的基本前提。

atomic是原子的意思,意味"不可分割"的整體。在linux kernel中有一類atomic操作api。這些操作對使用者而言是原子執行的,在乙個cpu上執行過程中,不會被其他cpu打斷。最常見的操作是原子讀改寫,簡稱rmw。

原子操作需要硬體的支援,檢視核心原始碼中的atomic_*函式,最終都是採用彙編執行,通過鎖記憶體匯流排、記憶體屏障等方式來實現的。下一章會以cas方法(例x86指令cmpxchgl)來舉例說明。

原子操作主要用於實現資源計數,很多引用計數就是通過原子操作實現的。原子型別定義如下:

typedef struct  atomic_t;

volatile修飾字段告訴gcc不要對該型別的資料做優化處理。

對它的訪問都是對記憶體的訪問,而不是對暫存器的訪問。

原子操作api包括:

atomic_read(atomic_t * v);

該函式對原子型別的變數進行原子讀操作,它返回原子型別的變數v的值。

atomic_set(atomic_t * v, int i);

該函式設定原子型別的變數v的值為i。

void atomic_add(int i, atomic_t *v);

該函式給原子型別的變數v增加值i。

atomic_sub(int i, atomic_t *v);

該函式從原子型別的變數v中減去i。

int atomic_sub_and_test(int i, atomic_t *v);

該函式從原子型別的變數v中減去i,並判斷結果是否為0,如果為0,返回真,否則返回假。

void atomic_inc(atomic_t *v);

該函式對原子型別變數v原子地增加1。

void atomic_dec(atomic_t *v);

該函式對原子型別的變數v原子地減1。

int atomic_dec_and_test(atomic_t *v);

該函式對原子型別的變數v原子地減1,並判斷結果是否為0,如果為0,返回真,否則返回假。

int atomic_inc_and_test(atomic_t *v);

該函式對原子型別的變數v原子地增加1,並判斷結果是否為0,如果為0,返回真,否則返回假。

int atomic_add_negative(int i, atomic_t *v);

該函式對原子型別的變數v原子地增加i,並判斷結果是否為負數,如果是,返回真,否則返回假。

int atomic_add_return(int i, atomic_t *v);

該函式對原子型別的變數v原子地增加i,並且返回指向v的指標。

int atomic_sub_return(int i, atomic_t *v);

該函式從原子型別的變數v中減去i,並且返回指向v的指標。

int atomic_inc_return(atomic_t * v);

該函式對原子型別的變數v原子地增加1並且返回指向v的指標。

int atomic_dec_return(atomic_t * v);

該函式對原子型別的變數v原子地減1並且返回指向v的指標。

gcc內建的__sync_*函式提供了加減和邏輯運算的原子操作,一共有十二個函式

type __sync_fetch_and_add (type *ptr, typevalue)

;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, typevalue)

;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)

;

type可以是1,2,4或8位元組長度的int型別,即:

int8_t / uint8_t

int16_t / uint16_t

int32_t / uint32_t

int64_t / uint64_t

(1)匯流排鎖bus lock:使用處理器提供乙個lock#訊號,當乙個處理器在匯流排上輸出此訊號的時候,其他處理器的請求將被阻塞,那麼該處理器可以獨佔使用共享記憶體。匯流排鎖是把cpu和記憶體之間通訊鎖住了,這使得鎖定期間,其他處理器不能操作其他記憶體位址的資料,所以匯流排鎖鎖定的開銷比較大。

(2)快取鎖定cacheline lock:基本都採用快取一致性協議(mesi)。

這部分可以參考:

《現代作業系統:原書第4版》:第8章:多處理機系統

說說無鎖(lock-free)程式設計那些事:

《現代作業系統:原書第4版》

《多核程式設計入門》

atomic實現原理:

cache之多核一致性(一) - 匯流排上沒有秘密:

原子操作以及加鎖機制:

說說無鎖(lock-free)程式設計那些事:

GPU程式設計和流式多處理器(七)

將第二個運算 加,最小或最大值 應用於中間結果和第三個運算數。通過引用內建變數threadidx,blockidx,blockdim和griddim,訪問許多特殊暫存器。這些偽變數將在3節中詳細介紹,它們是3維結構,分別指定執行緒id,塊id,執行緒數和塊數。除此之外,另乙個特殊暫存器,sm的時鐘暫...

多處理器程式設計的藝術 pdf格式

多處理器程式設計的藝術 從原理和實踐兩個方面全面闡述了多處理器程式設計的指導原則,包含編制高效的多處理器程式所必備的演算法技術。此外,附錄提供了採用其他程式語言包 如c c及c 的pthreads庫 進行程式設計的相關背景知識以及硬體基礎知識。多處理器程式設計的藝術 適合作為高等院校計算機及相關專業...

作業系統(3) 多處理器程式設計 從入門到放棄

入門 理解多執行緒 三個放棄 原子性 有序性 可見性 程序與執行緒的區別 執行緒的建立 include include include void mythread void arg intmain int argc,char ar 執行結果 可以看到,執行緒建立後,可能立即執行,也可能處於就緒狀態,...