Linux原子操作,讀寫鎖機制

2021-08-31 21:07:02 字數 1907 閱讀 1837

若干組合語言指令具有「讀--修改--寫」型別 。也就是說,他們訪問儲存單元兩次,第一次讀原值,第二次寫新值。

假定執行在兩個cpu上的兩個核心控制路徑試圖通過執行非原子操作來同時「讀--修改--寫」同乙個儲存器單元。首先,兩個cpu都試圖讀同乙個單元,但是儲存器仲裁器(對訪問ram晶元的操作進行序列化的硬體電路)插手,只允許其中乙個訪問而不讓另乙個延遲。然而,當第乙個讀操作已經完成後,延遲的cpu從哪個儲存器單元正好讀到同乙個(舊)值。然而,兩個cpu都試圖向那個儲存器單元寫一新值,匯流排儲存器訪問再一次被儲存器總裁器序列化,最終,兩個寫操作都成功。但是,全域性的結果是不對的,因為兩個cpu寫入同一(新)值。因此,兩個交錯的「讀--修改--寫」操作了乙個單獨的操作。

避免由於「讀--修改--寫」指令引起的競爭條件的最容易的辦法,就是確保這樣的操作在晶元級是原子的。任何乙個這樣的操作都必須以單個指令執行,中斷不能中斷,且避免其他的cpu訪問同一儲存器單元。這些很小的原子操作可以建立在其他更靈活進製的基礎之上以建立臨界區。

在你編寫c**程式時,並不能保證編譯器會為a = a +1 或甚至像  a ++這樣的操作使用乙個原子指令。因此linux核心提供了乙個專門的 atomic_t 型別(乙個原子訪問計數器)和一些專門的函式和巨集, 這些函式和巨集作用於atomic_t 型別的變數,並當做單獨的、原子的組合語言指令來使用。在多處理器系統中,每條這樣的指令都有乙個lock位元組的字首。

1. linux 中原子操作

atomic_read(v)                    返回*v

atomic_set(v, i)                  把*v 置成 i

atomic_add(i,v)               給*v 增加 i

atomic_add_return(i,v)   把i 加到*v,返回*v的新值

atomic_sub(i, v)              從*v 中減去i 

atomic_sub_reurn(i,v)     從*v減i, 返回*v的新值

atomic_sub_and_test(i,v)    從*v中減去i, 如果結果為0 則返回1;否則,返回0

atomic_inc(v)                     把1加到*v

atomic_dec(v)                        從*v減 1

atomic_inc_return(v)        把1加到*v,返回*v新值

atomic_dec_return(v)      從*v減1 ,返回* v的新值

2. linux 中原子位操作

test_bit(nr, addr)       返回*add的第nr位的值

set_bit(nr,addr)         設定*addr的第nr位

clear_bit(nr,addr)      清*addr的第nr位

change_bit(nr, addr)         轉換*addr的第nr位,並返回他的原值

3. linux讀寫鎖

讀/寫自旋鎖的引入是為了增加核心的併發能力。只要沒有核心控制路徑對資料結構進行修改,讀/寫自旋鎖就允許多個核心控制路徑同時讀取同乙個資料結構,如果乙個核心控制路徑相對這個結構進行寫操作,那麼他必須首先獲取讀/寫鎖的寫鎖,寫鎖授權獨佔訪問這個資源。當然,允許對資料結構併發讀可以提高系統效能。

下圖顯示兩個受讀/寫鎖保護的臨界區(c1 和 c2 )。核心控制路徑r0和r1正在同時讀取c1 中資料結構,而w0,正等待獲取寫鎖。核心控制路徑w1 正對c2 中 的資料結構進行寫操作,而r2 和w2 分別等待獲取讀鎖和寫鎖

linux 訊號量

原子操作 普通鎖 讀寫鎖

一 原子操作cas compare and swap 原子操作分三步 讀取addr的值,和old進行比較,如果相等,則將new賦值給 addr,他能保證這三步一起執行完成,叫原子操作也就是說它不能再分了,當有乙個cpu在訪問這塊內容addr時,其他cpu就不能訪問 text compareandsw...

Linux核心併發機制 原子操作

很多人會問這樣的問題,linux核心中提供了各式各樣的鎖機制到底有何作用?追根到底其實是由於作業系統中存在多程序對共享資源的併發訪問,從而引起了程序間的競態。這其中包括了我們所熟知的smp系統,多核間的相互競爭資源,單cpu之間的相互競爭,中斷和程序間的相互搶占等諸多問題。所謂的原子操作,就是該操作...

Linux 同步機制 讀寫鎖

讀寫鎖也叫 shared exclusive 鎖,也是一種同步機制。讀寫鎖有三種狀態 讀模式下加鎖,寫模式下加鎖,不加鎖。有如下的使用約定 讀模式共享,寫模式獨佔,適合讀頻率遠大於寫頻率的場景。這些api位於 pthread.h 下。initialize read write lock rwlock...