Linux核心設計與實現 10 核心同步介紹

2021-07-29 17:35:36 字數 2385 閱讀 2516

臨界區:就是訪問和操作共享資料的**段。

如果兩個執行執行緒有可能處於同乙個臨界區中同時執行,如果這個情況發生了,就叫做競爭條件。避免併發和防止競爭條件稱為同步。

我們必須在某些操作期間對資料加鎖,確保每個事務相對其他操作是原子性的,這樣的事務必須完整地發生,要麼乾脆不發生,但是決不能打斷。

對於單個變數的訪問,也有可能發生競爭;因為把變數從記憶體拷貝到暫存器,再修改暫存器值,然後重新寫回記憶體,這個過程是可以併發執行的,多數處理器提供原子指令來操作變數,這樣也可以解決併發問題。

當共享資源是乙個複雜的資料結構時,競爭條件往往會使該資料結構遭到破壞。鎖就是一種保護共享資料的機制,任何執行緒先持有鎖,才能運算元據,這保護了資料的安全,操作完成後也必須釋放鎖。

鎖是採用原子操作實現的,而原子操作不存在競爭。

(1)

造成併發的原因

①中斷:

中斷幾乎可以在任意時刻非同步發生,可能隨時打斷正在執行的**;

②軟中斷和

tasklet:

核心能在任意時刻喚醒或排程軟中斷和

tasklet,

打斷正在執行的**;

③核心搶占:

因為核心具有搶占性,所以核心中任務可能會被另一任務搶占;

④睡眠及使用者空間同步:

在核心執行的程序可能會睡眠,這就會喚醒排程程式,導致乙個新程序執行。

⑤對稱多處理器:

兩個或多個處理器可以同時執行**

對核心開發者來說,必須理解上訴併發執行的原因,並且為它們事先做足準備工作。

用鎖來保護共享資源並不難,但辨認出真正需要共享的資料和相應的臨界區,才是真正有挑戰性的地方。最好是在編寫**的開始階段就要涉及恰當的鎖。

(2)

了解要保護些什麼

大多數核心資料結構都需要加鎖!如果有其他執行執行緒可以訪問這些資料,那麼就給這些資料加上某種形式的鎖。注意:是給資料而不是給**加鎖。

編寫核心**時,要注意以下問題:

①這個資料是不是全域性的?除了當前執行緒外,其他執行緒能不能訪問他?

②這個資料會不會在程序上下文或中斷上下文共享?是不是要在兩個不同的中斷處理程式中共享?

③程序在訪問資料時可不可能被搶占?被排程的新程式會不會訪問同一資料?

④當前程序是不是會睡眠(阻塞)在某些資源上,如果是,它會讓共享資料處於何種狀態?

⑤怎樣防止資料失控?

⑥如果這個函式又在另乙個處理器上被排程將會發生什麼?

⑦如何確保**遠離併發威脅呢?

簡而言之,幾乎訪問所有核心全域性變數和共享資料都需要某種形式的同步方法。

死鎖的產生需要一定條件:要有乙個或多個執行執行緒和乙個或多個資源,每個執行緒都在等待其中的乙個資源,但所有的資源都已經被占用了。所有執行緒在互相等待,但它們永遠不會釋放已經占有的資源。

最簡單的死鎖例子是自死鎖:乙個執行執行緒檢視是獲得乙個自己已經持有的鎖。

(linux

沒有提供遞迴鎖)

預防死鎖的一些簡單規則:

①按順序加鎖。使用巢狀鎖時,所有執行緒都按系統的順序獲取鎖。

②防止發生飢餓,這個**的執行是否一定會結束?

③不要重複請求同乙個鎖。

④涉及應力求簡單

—越複雜的加鎖方案越有可能造成死鎖。

儘管釋放鎖的順序與死鎖無關,但最好還是以獲取鎖的相反順序來釋放鎖。

防止死鎖很重要,所以

linux

提供了一些簡單易用的除錯工具,可以在執行時檢測死鎖。

鎖的爭用

(lock contention):

是指當鎖正在被占用時,有其他執行緒試圖獲得該鎖。鎖乙個鎖處於高度爭用狀態,就是指有多個其他執行緒在等待獲取該鎖。由於鎖的作用是使執行緒以序列方式對資源進行訪問,所以使用鎖無疑會降低系統效能。

擴充套件性(scalability):

是對系統可擴充套件性的乙個量度。

對於作業系統,處理器,記憶體等可以被計量的計算機元件都可以涉及可擴充套件性。

linux2.6

核心中,核心加的鎖是非常細的力度,可擴充套件性很好。

當鎖太大,鎖爭用問題變得嚴重時,設計就向更加精細的加鎖方向進化。

一般來說,提高可擴充套件性是好事,因為可以提高

linux

在更大型、處理能力更強大的系統上的效能,但是一味「提高」可擴充套件性,卻會導致

linux

在小型smp和up

機器上的效能降低。因為小型機器可能用不到特別精細的鎖,鎖得過細緻會增加複雜度,並加大開銷。

如果在雙處理器機器上鎖爭用表現的並不明顯,那麼多餘的鎖會加大系統開銷,造成很大浪費。

鎖加的過粗或過細,差別往往只在一線之間,當鎖爭用嚴重時,加鎖太粗會降低可擴充套件性;而鎖爭用不明顯時,加鎖過細會加大系統開銷,帶來浪費,這兩種情況都會造成系統效能下降。

設計初期加鎖方案應該力求簡單,僅當需要時再進一步細化加鎖方案,精髓在於力求簡單。

1 給主人留下些什麼吧!~~

linux 核心設計與實現相關

有待繼續補充。第一章 linux核心簡介 需要注意 核心開發其實並不難。第二章 從核心出發 核心開發需要注意 1 沒有c庫,c庫太大了 2 沒有記憶體保護機制 3 不要輕易使用浮點數 4 可移植的重要性 5 同步和併發 疑問 編譯和安裝核心?必須在linux下麼?其他機器安裝了gcc編譯器呢?能否編...

Linux核心設計與實現總結。

1.程序管理。本章主要是介紹程序的乙個靜態的狀態,包括系統如何組織程序。建立,啟動,到最後死亡的乙個概念性認識,沒有更加深刻的知識。2.程序排程。本章比較重要。1.搶占式排程策略。2.倆程序間上下文切換 有倆函式 switch mm 和 switch to倆函式完成此功能。具體細節需要閱讀其他書籍 ...

linux核心設計與實現 前言

認真閱讀原始碼很重要,應該鑽研並嘗試著手改一些 尋找乙個bug然後去修改它,改進你的硬體裝置的驅動程式 unix特點 作業系統 指系統中負責完成最基本功能和系統管理的部分。包括 核心 裝置驅動程式 啟動引導程式 命令列shell或其他種類的使用者介面 基本的檔案管理和系統工具。核心組成 中斷服務程式...