1.必須先了解的基本概念1.1臨界區
一段**,在程式中多次被執行,每次執行的過程,我們稱之為**的執行路徑。
當不只乙個,及兩個或以上**路徑要競爭乙個共同的資源的時候,該**段就是臨界區。
那麼在有乙個線 程進入後其他所有試圖訪問此臨界區的執行緒將被掛起,並一直持續到進入臨界區的執行緒離開。
1.2互斥機制
訪問共享資源的**叫做臨界區。當共享資源被多個執行緒訪問,但是共享資源又不能被同時訪問。
所以呢,臨界區需要某種互斥機制來加以保護,確保共享資源被互斥訪問。
1.3使用者空間和核心空間
出於安全考慮,linux系統 分為核心態和使用者態,分別執行在核心空間和使用者空間。
核心態: 程式可以執行特權指令,作業系統本身也在其中執行。
使用者態:
1、 不允許直接訪問作業系統的核心資料、裝置等關鍵資源。
2、 先通過系統呼叫或者中斷進入核心態才可以訪問。
3、 當系統呼叫或中斷返回時,重新回到使用者空間執行。
2.linux 的互斥機制2.1中斷遮蔽
1.中斷是乙個完全非同步的事件,它的發生與正在執行的程序沒有任何關係,它沒有程序上下文切換。
cpu具備遮蔽中斷和開啟中斷的功能,這項功能可以保證正在執行的核心執行路徑不被中斷處理程式搶占,防止競態的產生。
2.但是,核心的正常執行依賴於中斷機制。在遮蔽中斷期間,任何中斷都無法得到處理,而必須等待遮蔽解除。因此長時間遮蔽中斷對核心的執行起到很大的影響,其後果可能導致資料丟失,甚至系統崩潰。
3. 實際情況是:在中斷服務全過程遮蔽中斷會丟失中斷;如果開中斷,又容易引起互斥問題。
4.為了解決這個問題,linux 把中斷分為頂半部th(top half)和底半部bh(bottom half)。
th 遮蔽中斷,執行一些少量的關鍵性動作;bh 可以開中斷,允許中斷延遲執行。
2.2原子操作
所謂原子操作,就是「不可中斷的乙個或一系列操作」。
原子操作,就是不能被更高等級中斷搶奪優先的操作。你既然提這個問題,我就說深一點。由於作業系統大部分時間處於開中斷狀態,所以,乙個程式在執行的時候可能被優先順序更高的執行緒中斷。而有些操作是不能被中斷的,不然會出現無法還原的後果,這時候,這些操作就需要原子操作。就是不能被中斷的操作。
2.3自旋鎖
是為實現保護共享資源而提出一種鎖機制。其實,自旋鎖與互斥鎖比較類似,它們都是為了解決對某項資源的互斥使用。無論是互斥鎖,還是自旋鎖,在任何時刻,最多只能有乙個保持者,也就說,在任何時刻最多只能有乙個執行單元獲得鎖。但是兩者在排程機制上略有不同。對於互斥鎖,如果資源已經被占用,資源申請者只能進入睡眠狀態。但是自旋鎖不會引起呼叫者睡眠,如果自旋鎖已經被別的執行單元保持,呼叫者就一直迴圈在那裡看是否該自旋鎖的保持者已經釋放了鎖,"自旋"一詞就是因此而得名。
事實上,自旋鎖的初衷是:在短期間內進行輕量級的鎖定。乙個被爭用的自旋鎖使得請求它的執行緒在等待鎖重新可用的期間進行自旋(特別浪費處理器時間),所以自旋鎖被持有的時間不應該過長。如果需要長時間鎖定的話, 最好使用訊號量。
(1)自旋鎖不能遞迴
(2)自旋鎖可以用在中斷上下文(訊號量不可以,因為可能睡眠),但是在中斷上下文中獲取自旋鎖之前要先禁用本地中斷,中斷是不參與系統排程的
(3)自旋鎖的核心要求是:擁有自旋鎖的**必須不能睡眠,要一直持有cpu直到釋放自旋鎖
2.4訊號量
訊號量物件對執行緒的同步方式與前面幾種方法不同,訊號允許多個執行緒同時使用共享資源,這與作業系統中的pv操作相同。它指出了同時訪問共享資源的執行緒 最大數目。它允許多個執行緒在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大執行緒數目。
3.總結:3.1中斷遮蔽:就是,有乙個人想要用廁所,但是呢他在上廁所前在門口貼上紙條說廁所壞了,如果他很快出來倒還不要緊,但是如果他要上很長時間,那一起住的其他人可能就要憋爆了。所以中斷遮蔽最開始不會被用於處理需要耗時很長的操作。但是大家想,這樣不是個解決辦法啊,我有時候確實要拉很長時間怎麼辦呢。
於是發明了頂半部th和底半部bh,th用於執行少量的關鍵性的動作,bh用於處理中斷中耗時的部分。
可以理解為,某人a特別特別想上廁所的時候,就進入th(可以看作乙個狀態),此時a去應個急,拉一點點,讓肚子不那麼疼,此時a是不可以被打斷的。如果沒人用廁所他就直接慢條斯理的開始拉了(bh)。但是他這個bh狀態是可以打斷的,如果此時來個人b 非常非常急,b進入th說,我受不了啦要憋死啦,a就會暫停自己的狀態(保護現場)讓b進來拉一會(th),等b拉了一點點,讓肚子不那麼疼了就出去。此時 a繼續(恢復現場)。等a 的bh部分完全結束後b再執行b的bh部分。
3.2原子操作:
很好理解,就是大家每次上廁所都用時非常短,短到什麼程度呢,只要一條彙編指令的時間。當然拉的量也非常少(只改變乙個整型或者是位)。所以就不存在搶廁所的問題了。
3.3自旋鎖:
顧名思義,給這個廁所上把鎖,只有擁有這個鎖鑰匙的人a才能進廁所。進去後把鎖鎖上,外面的人b急得團團轉(自旋),出來後把鎖釋放,在門口等著的b拿了鑰匙趕緊開了鎖進去了。但是缺點就是,b在外面團團轉,沒有功夫去做別的事情,所以一旦 a 上廁所的時間很長,b就浪費了很長時間在自旋上。對系統的效能有所影響。
3.4訊號量:
訊號量就是,我們的房子有 n 個廁所,n 不為 1, 且 n 為有限個,上廁所的人是有限的。即共享這一塊資源的程序是有限個數的。這時候我們就可以在廁所門口掛上 n 吧鑰匙,拿到鑰匙的就可以進去,鑰匙架空了,其他程序就只能在門口等待出來的人還鑰匙。
參考文獻:
參考文獻:
linux執行緒》同步互斥機制之 互斥鎖
本文基於訊號量 如果訊號量的值最多為1,那實際上相當於乙個共享資源在任意時刻最多只能有乙個執行緒在訪問,這樣的邏輯稱為 互斥 這時,有一種更加方便和語義更加準確的工具來滿足這種邏輯 互斥鎖。幾個執行緒同時去搶乙個鎖,誰搶到了鎖就進門把房間鎖上,訪問資料,出來後之前解鎖。照這樣的邏輯,互斥鎖的操作無非...
linux系統的互斥鎖機制
2016年12月16日 17 34 48 這兩天開始看linux下的執行緒程式設計,看到了關於互斥鎖這一塊兒,寫了乙個小例項如下 但是偶爾結果也會是這樣子的 就被掛起了,不執行向下的操作了。最後想來了問題所在 輸出1的那個執行緒如果先執行,輸出2的執行緒接下來執行,輸出3的執行緒最後執行。那麼到了p...
同步機制 互斥鎖
互斥鎖指代相互排斥,它是最基本的同步形式。互斥鎖用於保護臨界區,以保證任何時刻只有乙個執行緒在執行其中的 或者任何乙個時刻只有乙個程序在執行其中的 保護乙個臨界區的 的通常輪廓大體如下 lock the mutex 臨界區unlock the mutex posix互斥鎖被宣告為具有pthread ...