Linux的同步訪問技術

2022-09-02 02:06:12 字數 1578 閱讀 2650

1.中斷遮蔽:  

單cpu範圍內避免競態的一種簡單方法:在進入臨界區之前遮蔽系統的中斷。中斷遮蔽將使得中斷與程序之間的併發不再發生,而且linux核心的程序排程等操作都依賴中斷來實現,核心搶占式程序之間的併發也就得以避免。

操作步驟:

local_irq_disable()  //遮蔽中斷

critical section()    //臨界區

local_irq_enable()   //開啟中斷

中斷對於核心的執行非常重要,在遮蔽中斷期間的終端都無法得到處理,因此長時間的遮蔽中斷是很危險的,有可能造成資料丟失甚至是系統崩潰,所以在中斷遮蔽後,當前的核心執行路徑應當盡快的執行完臨界區的**。

2.原子操作:

原子操作->是在執行的過程中不會被別的**路徑所中斷的操作。

linux核心提供了一系列函式來實現核心中的原子操作,這些函式分為兩類:

1>針對位進行原子操作;2>針對整理變數進行原子操作。

共同點:在任何情況下操作都是原子的,核心**可以安全地呼叫它們而不會被打斷,都是依賴底層cpu的原子操作來實現的。

3.自旋鎖:

由於中斷遮蔽會使得中斷得不到響應,從而導致系統效能變差;原子操作受限於cpu,只能實現有限幾種基本資料型別的排他操作;linux設計了自旋鎖以實現共享資源的同步訪問。

自旋鎖(spin lock)是一種對臨界資源進行互斥訪問的典型手段。為了獲得乙個自旋鎖,在某cpu上執行的**需先執行乙個原子操作,該操作測試並設定(test-and-set)某個記憶體變數,由於是原子操作,所以該操作完成之前其他操作執行單元不可能訪問這個記憶體變數。若測試結果表明這個鎖已經空閒,則程式獲得這個自旋鎖並繼續執行,若測試結果表明這個鎖仍被占用,程式將在乙個小的迴圈內重複這個「測試並設定」操作,即進行所謂的「自旋」。當自旋鎖的持有者通過重置該變數釋放這個自旋鎖後,某個等待的變數「測試並設定」操作向其呼叫者報告鎖已釋放。

linux與自旋鎖有關的操作主要有以下4種:

(1)spinlock_t spin;     //定義自旋鎖

(2)spin_lock_init(lock);     //動態初始化自旋鎖lock

(3)spin_lock(lock);     //獲得自旋鎖  直到獲得  「可能會一直原地打轉」

spin_trylock(lock) ;    //獲得自旋鎖   只嘗試一次  「不會一直原地打轉」

(4)spin_unlock(lock);    //釋放自旋鎖

中斷處理程式不能使用自旋鎖,因為中斷處理程式中申請的自旋鎖被其他執行程式路徑所占有,會導致系統其他中斷得不到響應。

自旋鎖其實是忙等鎖,當鎖不可用時,cpu一直迴圈執行「測試並設定」該鎖直到可用而取得該鎖,cpu在等待自旋鎖時不做任何有用的工作,僅僅是等待,因此只有在占用鎖的時間極短的情況下使用自旋鎖才是合理的。當臨界區很大或有共享裝置的時候,需要較長時間占有鎖,使用鎖會降低系統的效能。

自旋鎖還可能會導致系統死鎖。遞迴使用乙個鎖即如果乙個已經擁有自旋鎖的cpu想要第二次獲得這個鎖,則該cpu將產生死鎖。此外還有程序獲得鎖後再阻塞,也可能導致死鎖。copy_from_user()、copy_to_user()、kmalloc()等函式都可能因為記憶體缺頁而阻塞,因此在自旋鎖占用期間不能呼叫這些函式。

Linux同步技術之條件變數

條件變數也是linux中的一種同步技術,不過其一般不單獨使用而是要和互斥鎖一起配合使用。如果單獨使用互斥量的話,很容易發生死鎖,所以條件變數為次應運而生 條件變數允許乙個執行緒阻塞和等待另乙個執行緒傳送的訊號,使用條件變數可以以原子的方式阻塞執行緒,直到滿足某個條件為止,可以避免忙等。條件變數通常和...

Linux中的同步技術之互斥量

互斥量從本質上說就像是一把鎖,提供資源的保護訪問,互斥量有兩種狀態,鎖住 lock 與解鎖狀態 unlock 用來保證一段時間內只有乙個執行緒使用該共享資源。互斥量的資料型別為pthread mutex t,如果互斥鎖變數是靜態分配的,那麼一般將其初始化為常值pthread mutex initia...

Linux 驅動分類 與訪問技術

驅動開發概述 1.驅動分類 1.1 常規分析法 1.1.1 字元裝置 字元裝置是一種按位元組來訪問的裝置,字元驅動則負責驅動字元裝置,這樣的驅動通常實現open,close,read和write 系統呼叫。例 串列埠,led,按鍵。1.1.2 塊裝置 在大部分的unix系統中,塊裝置定義為 以塊 通...