linux 原子變量

有時, 一個共享資源是一個簡單的整數值. 假設你的驅動維護一個共享變量 n_op, 它告 知有多少設備操做目前未完成. 正常地, 即使一個簡單的操做例如:ide

 

n_op++;函數

 

可能須要加鎖. 某些處理器可能以原子的方式進行那種遞減, 可是你不能依賴它. 可是一 個完整的加鎖體制對於一個簡單的整數值看來過度了. 對於這樣的狀況, 內核提供了一個 原子整數類型稱爲 atomic_t, 定義在 <asm/atomic.h>.測試

 

一個 atomic_t 持有一個 int 值在全部支持的體系上. 可是, 由於這個類型在某些處理 器上的工做方式, 整個整數範圍可能不是均可用的; 所以, 你不該當期望一個 atomic_tatom

 

持有多於 24 位. 下面的操做爲這個類型定義而且保證對於一個 SMP 計算機的全部處理 器來講是原子的. 操做是很是快的, 由於它們在任何可能時編譯成一條單個機器指令.資源

 

void atomic_set(atomic_t *v, int i); atomic_t v = ATOMIC_INIT(0);it

 

設置原子變量 v 爲整數值 i. 你也可在編譯時使用宏定義 ATOMIC_INIT 初始化原 子值.asm

 

int atomic_read(atomic_t *v); 返回 v 的當前值.編譯

void atomic_add(int i, atomic_t *v);class

 

由 v 指向的原子變量加 i. 返回值是 void, 由於有一個額外的開銷來返回新值, 而且大部分時間不須要知道它.test

 

void atomic_sub(int i, atomic_t *v); 從 *v 減去 i.void atomic_inc(atomic_t *v); void atomic_dec(atomic_t *v);

 

遞增或遞減一個原子變量.

 

int atomic_inc_and_test(atomic_t *v); int atomic_dec_and_test(atomic_t *v);

int atomic_sub_and_test(int i, atomic_t *v);

 

進行一個特定的操做而且測試結果; 若是, 在操做後, 原子值是 0, 那麼返回值是 真; 不然, 它是假. 注意沒有 atomic_add_and_test.

 

int atomic_add_negative(int i, atomic_t *v);

加整數變量 i 到 v. 若是結果是負值返回值是真, 不然爲假. int atomic_add_return(int i, atomic_t *v);

int atomic_sub_return(int i, atomic_t *v); int atomic_inc_return(atomic_t *v);

int atomic_dec_return(atomic_t *v);

 

就像 atomic_add 和其相似函數, 除了它們返回原子變量的新值給調用者.

 

如同它們說過的, atomic_t 數據項必須經過這些函數存取. 若是你傳遞一個原子項給一 個指望一個整數參數的函數, 你會獲得一個編譯錯誤.

 

你還應當記住, atomic_t 值只在當被置疑的量真正是原子的時候才起做用. 須要多個 atomic_t 變量的操做仍然須要某種其餘種類的加鎖. 考慮一下下面的代碼:

 

atomic_sub(amount, &first_atomic); atomic_add(amount, &second_atomic);

 

從第一個原子值中減去 amount, 可是尚未加到第二個時, 存在一段時間. 若是事情的 這個狀態可能產生麻煩給可能在這 2 個操做之間運行的代碼, 某種加鎖必須採用.

相關文章
相關標籤/搜索