自旋鎖和訊號量

2021-06-06 17:30:09 字數 2267 閱讀 3174

核心同步措施(用於linux核心)

為了避免併發,防止競爭。核心提供了一組同步方法來提供對共享資料的保護。 我們的重點不是介紹這些方法的詳細用法,而是強調為什麼使用這些方法和它們之間的差別。

linux使用的同步機制可以說從2.0到2.6以來不斷發展完善。從最初的原子操作,到後來的訊號量,從大核心鎖到今天的自旋鎖。這些同步機制的發展伴隨linux從單處理器到對稱多處理器的過度;伴隨著從非搶占核心到搶占核心的過度。鎖機制越來越有效,也越來越複雜。

目前來說核心中原子操作多用來做計數使用,其它情況最常用的是兩種鎖以及它們的變種:乙個是自旋鎖,另乙個是訊號量。我們下面就來著重介紹一下這兩種鎖機制。

自旋鎖自旋鎖是專為防止多處理器併發而引入的一種鎖,它在核心中大量應用於中斷處理等部分(對於單處理器來說,防止中斷處理中的併發可簡單採用關閉中斷的方式,不需要自旋鎖)。

自旋鎖最多只能被乙個核心任務持有,如果乙個核心任務試圖請求乙個已被爭用(已經被持有)的自旋鎖,那麼這個任務就會一直進行忙迴圈——旋轉——等待鎖重新可用。要是鎖未被爭用,請求它的核心任務便能立刻得到它並且繼續進行。自旋鎖可以在任何時刻防止多於乙個的核心任務同時進入臨界區,因此這種鎖可有效地避免多處理器上併發執行的核心任務競爭共享資源。

事實上,自旋鎖的初衷就是:在短期間內進行輕量級的鎖定。乙個被爭用的自旋鎖使得請求它的執行緒在等待鎖重新可用的期間進行自旋(特別浪費處理器時間),所以自旋鎖不應該被持有時間過長。如果需要長時間鎖定的話, 最好使用訊號量。

自旋鎖的基本形式如下:

spin_lock(&mr_lock);

//臨界區

spin_unlock(&mr_lock);

因為自旋鎖在同一時刻只能被最多乙個核心任務持有,所以乙個時刻只有乙個執行緒允許存在於臨界區中。這點很好地滿足了對稱多處理機器需要的鎖定服務。在單處理器上,自旋鎖僅僅當作乙個設定核心搶占的開關。如果核心搶占也不存在,那麼自旋鎖會在編譯時被完全剔除出核心。

簡單的說,自旋鎖在核心中主要用來防止多處理器中併發訪問臨界區,防止核心搶占造成的競爭。另外自旋鎖不允許任務睡眠(持有自旋鎖的任務睡眠會造成自死鎖——因為睡眠有可能造成持有鎖的核心任務被重新排程,而再次申請自己已持有的鎖),它能夠在中斷上下文中使用

死鎖:假設有乙個或多個核心任務和乙個或多個資源,每個核心都在等待其中的乙個資源,但所有的資源都已經被占用了。這便會發生所有核心任務都在相互等待,但它們永遠不會釋放已經占有的資源,於是任何核心任務都無法獲得所需要的資源,無法繼續執行,這便意味著死鎖發生了。自死瑣是說自己占有了某個資源,然後自己又申請自己已占有的資源,顯然不可能再獲得該資源,因此就自縛手腳了。

訊號量linux中的訊號量是一種睡眠鎖。如果有乙個任務試圖獲得乙個已被持有的訊號量時,訊號量會將其推入等待佇列,然後讓其睡眠。這時處理器獲得自由去執行其它**。當持有訊號量的程序將訊號量釋放後,在等待佇列中的乙個任務將被喚醒,從而便可以獲得這個訊號量。

訊號量的睡眠特性,使得訊號量適用於鎖會被長時間持有的情況;只能在程序上下文中使用,因為中斷上下文中是不能被排程的;另外當**持有訊號量時,不可以再持有自旋鎖。

訊號量基本使用形式為:

static declare_mutex(mr_sem);//宣告互斥訊號量

if(down_interruptible(&mr_sem))

//可被中斷的睡眠,當訊號來到,睡眠的任務被喚醒

//臨界區

up(&mr_sem);

訊號量和自旋鎖區別

雖然聽起來兩者之間的使用條件複雜,其實在實際使用中訊號量和自旋鎖並不易混淆。注意以下原則:

如果**需要睡眠——這往往是發生在和使用者空間同步時——使用訊號量是唯一的選擇。由於不受睡眠的限制,使用訊號量通常來說更加簡單一些。如果需要在自旋鎖和訊號量中作選擇,應該取決於鎖被持有的時間長短。理想情況是所有的鎖都應該盡可能短的被持有,但是如果鎖的持有時間較長的話,使用訊號量是更好的選擇。另外,訊號量不同於自旋鎖,它不會關閉核心搶占,所以持有訊號量的**可以被搶占。這意味者訊號量不會對影響排程反應時間帶來負面影響。

自旋鎖對訊號量

需求                           建議的加鎖方法

低開銷加鎖                           優先使用自旋鎖

短期鎖定                              優先使用自旋鎖

長期加鎖                              優先使用訊號量

中斷上下文中加鎖              使用自旋鎖

持有鎖是需要睡眠、排程     使用訊號量

自旋鎖和訊號量

今天在閱讀核心 時遇到了自旋鎖函式,於是查閱資料,學習了一下自旋鎖和訊號量的知識。自旋鎖 自旋鎖是專為防止多處理器併發而引入的一種鎖,它應用於中斷處理等部分。對於單處理器來說,防止中斷處理中的併發可簡單採用關閉中斷的方式,不需要自旋鎖。自旋鎖最多只能被乙個核心任務持有,如果乙個核心任務試圖請求乙個已...

自旋鎖,互斥鎖,訊號量

自旋鎖,互斥鎖,訊號量 樂觀鎖和悲觀鎖只是一種理論,是從思想上劃分的。自旋鎖和互斥鎖是應用層確確實實的鎖,用於同步訪問控制 如果一定要劃分,從只有乙個執行緒可以擁有鎖來說,我覺得自旋鎖和互斥鎖應該都屬於悲觀鎖,因為一般的應用不需要支援事物回滾的操作。但是沈詢的直播中說,互斥鎖屬於悲觀鎖 sleep ...

訊號量,互斥鎖,自旋鎖

個人理解 訊號量 程序間的通訊機制 單一個數的訊號 與訊息郵箱,訊息佇列,機理類同,量不同,用訊號量肯定掉cpu 自旋鎖 保護區域不掉cpu,持續查詢,等待 不可用時域長狀態 切記 時域範圍 在程序間的通訊機制函式狀態 鎖 0 互斥鎖與自旋鎖 互斥鎖 執行緒會從sleep 加鎖 running 解鎖...