1. 程式人生 > >自旋鎖--Test and Set Clock機制分析

自旋鎖--Test and Set Clock機制分析

自旋鎖–Test and Set Clock機制分析

@(OS)

自旋鎖:為防止多處理器併發引入的一種鎖。

在核心中,廣泛應用於中斷處理部分。而在單處理器中,防止中斷處理處理中的併發簡單採用關閉中斷即可,在PSW中開啟/關閉中斷標誌位,用不到自旋鎖。反之,用了自旋鎖機制,就不用再管開中斷或者關中斷

自旋鎖的設計初衷是忙則等待

理解

目的:為了實現保護共享資源,任何時刻只能有一個保持者。即只有一個程序可以獲得鎖。

自旋鎖機制下,如果自旋鎖已經被別的執行單元保持,那麼呼叫者就一直迴圈在那裡看自旋鎖的保持者是否釋放了鎖,即忙則等待。很多出題點喜歡在這個概念上混淆,故意出成讓權等待。讓全等待是出讓CPU,這裡沒有體現這個思路。因為跟CPU無關。自旋

是個很形象的動作,表示一直在原地運動,並未去睡眠。這是區別於互斥鎖的。

互斥鎖機制下,如果資源被佔用,資源申請者就會進入睡眠狀態

原理的理解

  • 執行單元想訪問被自旋鎖保護的共享資源,必須先獲得鎖。
  • 訪問完共享資源後,必須釋放鎖。

當準備去獲取自旋鎖時,發現鎖沒人在用,順利獲得鎖,可以訪問共享資源。否則,就一直在等。這就像在火車上用衛生間,如果空閒,就可以馬上進去,且把門鎖上,保護隱私。用完了把門開啟走掉。如果裡面有人,只好在外面等,如果著急,你肯定會一直等著,在那著急自旋。這就是自旋鎖機制。如果你不等了,回座位休息去,那就是互斥鎖機制。

自旋鎖是比較低階的保護資料結構,貼近硬體層面實現。

可能存在的問題:

  • 死鎖
  • 過多佔用CPU資源

推匯出自旋鎖適合使用者保持鎖時間較短的情況。

而訊號量機制適合保持鎖較長時間,因此沒有資源可用時去睡眠。

實現

多處理機互斥演算法:

do
{
    ...
    while(Test_And_Set_Lock(&lock)); //特別注意分號,以及傳遞的引數是引用引數
    //臨界區
    lock = False;
    //剩餘區
}while(True)

Test_And_Set_Lock函式是用硬體保持的原子執行,不被打斷。

特別注意while(Test_And_Set_Lock(&lock));這句後面是個分號就是說會迴圈等待解鎖。

理解到這個地步,就可以來思考一道真題了。

(2016.27)使用TSL指令實現程序互斥的虛擬碼如下:

do
{
    ...
    while(Test_And_Set_Lock(&lock)); //特別注意分號,以及傳遞的引數是引用引數
    //臨界區
    lock = False;
    //剩餘區
}while(True)

下列與該實現機制相關的敘述中,正確的是:
A. 退出臨界區的程序負責喚醒阻塞態程序
B. 等待進入臨界區的程序不會主動放棄CPU
C. 上述虛擬碼滿足“讓權等待”的同步準則
D. while(Test_And_Set_Lock(&lock))語句應在關中斷狀態下執行

分析:由上面的一大段分析可知,A項表述的是訊號量機制這些程序較長時才有的狀態,即程序無法訪問臨界資源時要去睡眠,在TSL裡,都是短程序,都是精力充沛的,忙則等待的型別。因此,沒人睡,自然也不存在喚醒。
C項讓權等待與B項表達的東西是相反的。讓權是什麼意思?有必要特別說明。讓權等待是一種策略,但是物件可以是CPU也可以是臨界資源。這要看具體語境。這裡,針對臨界資源的訪問,讓權等待是指:當程序不能進入臨界區時,應立即釋放處理器,防止程序忙等待。我們需要形成一種概念是,程序是程式的動態執行過程,忙則等待資源時,必然是在執行的程序,是有CPU在背後力挺的,睡眠就是說沒有資源趕緊滾,別佔著CPU!

想一想程序排程的三大基本形態:就緒態,執行態,阻塞態三態之間的互相轉化。

因此,C項錯,B項對,忙則等待就是要佔著CPU,所幸的是程序不長,否則遞迴呼叫一定產生死鎖。

D項是很細緻的考察,前面專門提過,TSL是多處理器下的程序併發問題,只有在中斷機制下采用PSW,關中斷/開中斷方式來進行程序的併發控制。

相關推薦

--Test and Set Clock機制分析

自旋鎖–Test and Set Clock機制分析 @(OS) 自旋鎖:為防止多處理器併發引入的一種鎖。 在核心中,廣泛應用於中斷處理部分。而在單處理器中,防止中斷處理處理中的併發簡單採用關閉中斷即可,在PSW中開啟/關閉中斷標誌位,用不到自旋鎖。反之,

018.多執行緒-悲觀、樂觀、重入、讀寫、CAS無機制

悲觀鎖(Pessimistic Lock) 顧名思義,就是很悲觀。每次去拿資料的時候都認為別人會修改,所以都會上鎖。這樣別人想拿這個資料就會阻塞(block)直到它拿到鎖。傳統的關係型資料庫裡面就用到了很多這種鎖機制。比如:行鎖,表鎖,讀鎖,寫鎖等,都是在做操作之前先上鎖。

機制-、偏向、輕量級、重量級

自旋鎖 如果持有鎖的執行緒能在很短時間內釋放鎖資源,那麼那些等待競爭鎖的執行緒就不需要做核心態和使用者態之間的切換進入阻塞掛起狀態,只需讓執行緒執行一個忙迴圈(自旋),等持有鎖的執行緒釋放鎖後即可立即獲取鎖,這樣就避免使用者執行緒和核心的切換的消耗。 自旋等

JAVA機制-可重入,可中斷,公平,讀寫

部落格引用處(以下內容在原有部落格基礎上進行補充或更改,謝謝這些大牛的部落格指導): JAVA鎖機制-可重入鎖,可中斷鎖,公平鎖,讀寫鎖,自旋鎖 在併發程式設計中,經常遇到多個執行緒訪問同一個 共享資源 ,這時候作為開發者必須考慮如何維護資料一致性,在java中synchronized

[Linux]互斥機制(中斷遮蔽、原子操作、、訊號量)

基本概念 臨界區 對某段程式碼而言,可能會在程式中多次被執行,每次執行的過程我們稱作程式碼的執行路徑。 當兩個或多個程式碼路徑要競爭共同的資源的時候,該程式碼段就是臨界區。 互斥機制 訪問共享資源的程式碼叫做臨界區。共享資源被多個執行緒需要

執行緒同步機制(互斥量,讀寫,條件變數,屏障)

先知:      (1)執行緒是由程序建立而來,是cpu排程的最小單位。      (2)每個程序都有自己獨立的地址空間,而程序中的多個執行緒共用程序的資源,他們只有自己獨立的棧資源。 執行緒同步:      當多個控制執行緒共享相同的記憶體時,需要確保每個程序看到一致的

pre 自旋 線程鎖 虛擬機 鎖競爭 pinning 取消 lock 等待 自旋鎖 自旋鎖可以使線程在沒有取得鎖的時候,可以不放棄CPU時間片,不被掛起,而轉去執行一個空循環,(即所謂的自旋,就是自己執行空循環),若在若幹個空循環後,線程如果可以獲得鎖,則繼續執行。若線程

本地與信號量/多服務臺隊列-spin wait風格的信號量

我們 一件事 以及 睡眠 為我 這也 鎖改變 蘇打水 mic 周日傍晚,我去家附近的超市(...)買蘇打水,準備自制青檸蘇打。我感覺我做的比買的那個巴黎水要更爽口。由於天氣太熱,非常多人都去超市避暑去了,超市也不攆人,這仿佛是他們的策略。人過來避暑了,走的時候難免要買些東

java

是否 ext 並且 大量 需要 命中率 logs div 共享 一 Test-and-Set Lock 所謂測試設置是最基本的鎖,每個線程共用一把鎖,進入臨界區之前看沒有有線程在臨界區,如果沒有,則進入,並上鎖,如果有則等待。java實踐中利用了原子的設置state變量來保

,讀寫和順序的實現原理

並且 保護 表達 min 返回 create creat rwlock ini 常用的同步原語鎖,到多核處理器時代鎖已經是必不可少的同步方式之一了。無論設計多優秀的多線程數據結構,都避不開有競爭的臨界區,此時高效的鎖顯得至關重要。鎖的顆粒度是框架/程序設計者所關註的,

linux 和信號量【轉】

you 修改 變種 能夠 體系結構 當下 top 數據 啟用 轉自:http://blog.csdn.net/xu_guo/article/details/6072823 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 自旋鎖最多只能被一個可執行線程

讀寫

adr 一個 失敗 基本 獲得 圖書館 不能 color pre 概述:   在一些程序中存在讀者寫者問題,也就是說,對某些資源的訪問會 存在兩種可能的情況,一種是訪問必須是排它行的,就是獨占的意思,這稱作寫操作; 另一種情況就是訪問方式可以是共享的,就是說可以有多個線程

Windows和pthread中提供的

sting CQ ++ next 應用層 and 中斷 實現 swa Windows和POSIX中都提供了自旋鎖,我們也可以通過C++11的atomic來實現自旋鎖。那麽兩者性能上面是什麽關系?先引入實現代碼: #ifndef __spinlock_h__ #define

Java---偏向、輕量級、重量級

center jdk1 startup 例如 單元 cati 保護 讀鎖 text 之前做過一個測試,反復執行過多次,發現結果是一樣的: 1. 單線程下synchronized效率最高(當時感覺它的效率應該是最差才對); 2. AtomicInteger效率最不穩定,不同並

C++ 11

c++ chan c-s pre eas load exchange spin lock unlock // Spin lock implementation. // BasicLockable. // Async-signal safe. // unlock()

多線程中的系統(四)-談談

輸出 成功 title 處理 -c 最好的 else if ofa ole 閱讀目錄: 基礎 自旋鎖示例 SpinLock 繼續SpinLock 總結 基礎 內核鎖:基於內核對象構造的鎖機制,就是通常說的內核構造模式。用戶模式構造和內核模式構造 優

偏向++輕量級??????

lock 當前 span sed 需要 back 默認 ase -c 首先了解對象頭MARK(對象頭標記,32位): 存儲GC標記,對象年齡,對象Hash,鎖信息(鎖記錄的指針,偏向鎖線程的ID) 大部分情況是沒有競爭的,所以可以通過偏向來提高性能 所謂的偏向,即鎖會偏向

linux 和信號量

鎖死 something urn 問題: 循環 系統 編譯錯誤 detail 同步機制 自旋鎖最多只能被一個可執行線程持有(讀寫自旋鎖除外)。自旋鎖不會引起調用者睡眠,如果一個執行線程試圖獲得一個已經被持有的自旋鎖,那麽線程就會一直進行忙循環,一直等待下去(一直占用 CPU

Linux內核

table line 只有一個 != 操作系統 不讓 正數 關閉 sta 自旋鎖 自旋鎖(spinlock)是用在多個CPU系統中的鎖機制,當一個CPU正訪問自旋鎖保護的臨界區時,臨界區將被鎖上,其他需要訪問此臨界區的CPU只能忙等待,直到前面的CPU已訪問完臨界區,將臨

Linux 核心

  為什麼需要核心自旋鎖? 現在很多CPU都是幾核幾核的了,如果有一個變數A,CPU-X正在訪問,突然CPU-Y也過來訪問他,這時候就可能出現問題,因為這個A非常重要,可能導致系統崩潰,中斷異常等。 我們來看之前說的TP驅動裡面的程式碼 void gtp_irq_ena