Linux核心中的同步機制

2021-08-25 17:38:33 字數 1913 閱讀 7705

與其解釋什麼是同步,倒不如告訴讀者同步的由來。在linux核心中,同步技術是為了解決問題而產生的。 說起這個問題,不得不提起可重入核心。

可重入核心執行多個程序交替執行,而程序的切換就發生在核心態下。程序的切換就意味著a程序還未執行結束,就要換b程序執行,如果存在全域性變數g,一旦程序切換,這意味著a程序失去對g的控制,其他程序可能對g進行修改等操作,當a程序再次執行時,a程序根本無法知道此時的全域性變數g的值還是否是當初程序切換前的那個g。這時候再貿然使用g可能導致致命的後果。

如果還不清楚,舉個例子。小明房間裡有一雙滑板鞋,早上起床上學時看到還在,於是在學校裡和同學約好下課一塊玩滑板,結果小明房間的門沒有鎖,在小明離開房間期間,他的弟弟進入房間將滑板拿走了,等小明回去一看,滑板鞋已經不在了。造成的後果就是小明將失信於同學,解決辦法就是將房間鎖住。

因此,無論是因為併發(多個程序交替執行)還是因此並行(多cpu)而產生的多個程序訪問同一資源時,就會產生資源訪問競爭,或者說資源訪問的順序及何時獲取及釋放資源。

如果上面a程序或b程序讀全域性變數g後又修改了g的值,那麼讀和修改操作應該是乙個單獨的、不可中斷的操作。否則,一旦程序切換,g的值則就變得不明確了。我們將這些不可中斷的操作放到臨界區來保證不可中斷的特性。那麼所謂的臨界區就是這樣一段**,進入這段**的程序必須完整的執行完這段**,否則,即使程序發生切換,另乙個程序也不可能進入這段**。

同步技術就是為了解決資源訪問競爭產生問題的一種方法。

linux核心同步有如下幾種方式:

針對資源訪問的不同需求而使用不同的同步方式,有些同步方法可以相互適用,但是所依據的法則是:把系統中的併發度保持在盡可能高的程度。

正如其名,每cpu變數即為每個cpu都有自己的變數,各個cpu僅訪問自己的每cpu變數,可以想象每cpu變數一般的資料結構是乙個陣列。

type name[cpu_count];
因此每cpu變數解決的是多cpu之間可能發生的競爭條件,而因核心搶占而產生了程序切換時,則很可能使每cpu變數產生競爭條件,就像之前舉的那個例子一樣。

想必讀者對這個概念比較熟悉。原子操作即在執行原子操作時,不可能被在執行的時候拆分成幾條原子操作。

linux核心通過一些手段來實現某些操作的原子性,例如

簡單的說,優化編譯器會將原本的**進行重排,已達到最優的處理方式,這樣產生的問題是程式在執行的時候訪問記憶體的順序可能並不像我們程式中原本寫的那樣。當同步發生時(競爭條件),我們必須避免指令重排。

而優化屏障的意思就是在指令之間插入一道屏障,讓這道屏障之前和之後的指令不可能因重排而跨越這道屏障,很形象吧。

自旋鎖是一種廣泛的同步技術,它鎖住的是一塊臨界區,進入臨界區時需要先獲取自旋鎖,在離開臨界區時需要釋放自旋鎖。如果已經有其他程序獲取了該鎖,那麼當前想要獲取該鎖的程序只能在臨界區門口來回溜達(自旋),直到獲取該鎖。自旋鎖類似於現實生活中的給房間的門上鎖,進入房間訪問資源時需要鎖住門,防止其他人同時進入房間,退出房間時,再開啟鎖。

這種自旋鎖的特點是允許多個程序同時對同一資料結構進行讀,但不允許多個程序同時修改同一資料結構,因此在實現上必須分為讀鎖和寫鎖。讀鎖要實現多個程序能同時讀同一資料結構,但是讀的過程中不允許寫,寫鎖要實現僅能有乙個程序獲取寫鎖進入臨界區,獲取寫鎖時同時保證沒有程序已經獲取讀鎖。

實現:至於讀寫鎖的實現,事實上用乙個變數即可實現,讀者可以思考下如何設計。

順序鎖和讀寫鎖的區別就是順序鎖中,寫鎖可以在程序還未釋放讀鎖的情況下獲取寫鎖,這樣寫鎖不會因為讀鎖而等待,但是讀程序在讀的時候必須考慮是否有寫程序正在進行寫操作。

訊號量和自旋鎖類似,也是為了控制程序進入臨界區,但是訊號量和自旋鎖的重大區別是:

文字介紹了linux核心中幾種同步方式,關鍵在於理解同步發生的原因,才能想辦法去解決同步競爭條件,剩下的則是根據具體問題,設計具體的同步機制,文中並沒有詳細介紹各種鎖的實現機制,感興趣的讀者可以參考相關書籍資料。

參考資料

《深入理解linux核心》

順序鎖

核心同步機制

1.通過鎖機制來實現同步,有兩種不同的鎖,一種是鎖被持有時選擇忙等,一種是選擇睡眠等待。2.如何避免死鎖 a.按順序加鎖 b.不要重複加鎖 3.自旋鎖 spin lock 忙等鎖,樂觀 適合持有時間非常短,這是因為要考慮程序上下文切換的開銷。4.訊號量 檢視獲取乙個鎖時候,如果不可用則進入睡眠佇列 ...

linux同步機制

一.併發控制 1 自旋鎖 得不到資源,會原地打轉,直到獲得資源為止 定義自旋鎖 spinlock t spin 初始化自旋鎖 spin lock init lock 獲得自旋鎖 spin lock lock 獲得自旋鎖,如果能立即獲得,則馬上返回,否則自旋在那裡,直到該自旋鎖的保持者釋放 spin ...

linux同步機制

原子操作 原子操作是由編譯器來保證的,保證乙個執行緒對資料的操作不會被其他執行緒打斷。當執行緒正在對乙個變數操作而這個操作過程不想被其他執行緒打斷時,可以用原子操作,原子操作結構體 atomic t 原子操作缺點 會阻塞優先順序很高的執行緒。自旋鎖 當乙個執行緒在讀寫乙個共享資源時,加上自旋鎖,其他...