Linux內(nèi)核主要由5個(gè)模塊構(gòu)成,分別是:進(jìn)程調(diào)度模塊、內(nèi)存管理模塊、虛擬文件系統(tǒng)模塊、進(jìn)程間通信模塊。
Linux經(jīng)常使用散列表來實(shí)現(xiàn)高速緩存,高速緩存是需要快速訪問的信息。
Linux為什么需要同步機(jī)制?
在操作系統(tǒng)引入了進(jìn)程概念,進(jìn)程成為調(diào)度實(shí)體后,系統(tǒng)就具備了并發(fā)執(zhí)行多個(gè)進(jìn)程的能力,但也導(dǎo)致了系統(tǒng)中各個(gè)進(jìn)程之間的資源競爭和共享。另外,由于中斷、異常機(jī)制的引入,以及內(nèi)核態(tài)搶占都導(dǎo)致了這些內(nèi)核執(zhí)行路徑(進(jìn)程)以交錯(cuò)的方式運(yùn)行。對于這些交錯(cuò)路徑執(zhí)行的內(nèi)核路徑,如不采取必要的同步措施,將會(huì)對一些關(guān)鍵數(shù)據(jù)結(jié)構(gòu)進(jìn)行交錯(cuò)訪問和修改,從而導(dǎo)致這些數(shù)據(jù)結(jié)構(gòu)狀態(tài)的不一致,進(jìn)而導(dǎo)致系統(tǒng)崩潰。因此,為了確保系統(tǒng)高效穩(wěn)定有序地運(yùn)行,linux必須要采用同步機(jī)制。
Linux內(nèi)核提供了哪些同步機(jī)制?
在學(xué)習(xí)linux內(nèi)核同步機(jī)制之前,先要了解以下預(yù)備知識(shí):(臨界資源與并發(fā)源)
在linux系統(tǒng)中,我們把對共享的資源進(jìn)行訪問的代碼片段稱為臨界區(qū)。把導(dǎo)致出現(xiàn)多個(gè)進(jìn)程對同一共享資源進(jìn)行訪問的原因稱為并發(fā)源。
Linux系統(tǒng)下并發(fā)的主要來源有:
中斷處理:例如,當(dāng)進(jìn)程在訪問某個(gè)臨界資源的時(shí)候發(fā)生了中斷,隨后進(jìn)入中斷處理程序,如果在中斷處理程序中,也訪問了該臨界資源。雖然不是嚴(yán)格意義上的并發(fā),但是也會(huì)造成了對該資源的競態(tài)。
內(nèi)核態(tài)搶占:例如,當(dāng)進(jìn)程在訪問某個(gè)臨界資源的時(shí)候發(fā)生內(nèi)核態(tài)搶占,隨后進(jìn)入了高優(yōu)先級(jí)的進(jìn)程,如果該進(jìn)程也訪問了同一臨界資源,那么就會(huì)造成進(jìn)程與進(jìn)程之間的并發(fā)。
多處理器的并發(fā):多處理器系統(tǒng)上的進(jìn)程與進(jìn)程之間是嚴(yán)格意義上的并發(fā),每個(gè)處理器都可以獨(dú)自調(diào)度運(yùn)行一個(gè)進(jìn)程,在同一時(shí)刻有多個(gè)進(jìn)程在同時(shí)運(yùn)行 。
如前所述可知:采用同步機(jī)制的目的就是避免多個(gè)進(jìn)程并發(fā)并發(fā)訪問同一臨界資源。
Linux內(nèi)核中9種同步機(jī)制
1)每CPU變量
主要形式是數(shù)據(jù)結(jié)構(gòu)的數(shù)組,系統(tǒng)中的每個(gè)CPU對應(yīng)數(shù)組的一個(gè)元素。
使用情況:數(shù)據(jù)應(yīng)在邏輯上是獨(dú)立的
使用原則:應(yīng)在內(nèi)核控制路徑禁用搶占的情況下訪問每CPU變量。
2)原子操作
原理:是借助于匯編語言指令中對“讀--修改--寫”具有原子性的匯編指令來實(shí)現(xiàn)。
3)內(nèi)存屏障
原理:使用內(nèi)存屏障原語確保在原語之后的操作開始之前,原語之前的操作已經(jīng)完成。
4)自旋鎖
主要用于多處理器環(huán)境中。
原理:如果一個(gè)內(nèi)核控制路徑發(fā)現(xiàn)所請求的自旋鎖已經(jīng)由運(yùn)行在另一個(gè)CPU上的內(nèi)核控制
路徑“鎖著”,就反復(fù)執(zhí)行一條循環(huán)指令,直到鎖被釋放。
說明:自旋鎖一般用于保護(hù)禁止內(nèi)核搶占的臨界區(qū)。
在單處理器上,自旋鎖的作用僅是禁止或啟用內(nèi)核搶占功能。
5)順序鎖:
順序鎖與自旋鎖非常相似,僅有一點(diǎn)不同,即順序鎖中的寫者比讀者有較高的優(yōu)先級(jí),也就
意味著即使讀者正在讀的時(shí)候也允許寫者繼續(xù)運(yùn)行。
?。叮㏑CU
主要用于保護(hù)被多個(gè)CPU讀的數(shù)據(jù)結(jié)構(gòu)。
允許多個(gè)讀者和寫者同時(shí)運(yùn)行,且RCU是不用鎖的。
使用限制:
?。保㏑CU只保護(hù)被動(dòng)態(tài)分配并通過指針引用的數(shù)據(jù)結(jié)構(gòu)
?。玻┰诒籖CU保護(hù)的臨界區(qū)中,任何內(nèi)核控制路徑都不能睡眠。
原理:
當(dāng)寫者要更新數(shù)據(jù)時(shí),它通過引用指針來復(fù)制整個(gè)數(shù)據(jù)結(jié)構(gòu)的副本,然后對這個(gè)副本進(jìn)行
修改。修改完畢后,寫者改變指向原數(shù)據(jù)結(jié)構(gòu)的指針,使它指向被修改后的副本,(指針
的修改是原子的)。
?。罚?a target="_blank">信號(hào)量:
原理: 當(dāng)內(nèi)核控制路徑試圖獲取內(nèi)核信號(hào)量所保護(hù)的忙資源時(shí),相應(yīng)的進(jìn)程被掛起;只有在
資源被釋放時(shí),進(jìn)程才再次變?yōu)榭蛇\(yùn)行。
使用限制:只有可以睡眠的函數(shù)才能獲取內(nèi)核信號(hào)量 ;
中斷處理程序和可延遲函數(shù)都不能使用內(nèi)核信號(hào)量。
8)本地中斷禁止
原理:本地中斷禁止可以保證即使硬件設(shè)備產(chǎn)生了一個(gè)IRQ信號(hào)時(shí),內(nèi)核控制路徑也會(huì)繼續(xù)運(yùn)行,
從而使中斷處理例程訪問的數(shù)據(jù)結(jié)構(gòu)受到保護(hù)。
不足:禁止本地中斷并不能限制運(yùn)行在另一個(gè)CPU上的中斷處理程序?qū)蚕頂?shù)據(jù)結(jié)構(gòu)的并發(fā)訪問,
故在多處理器環(huán)境中,禁止本地中斷需要與自旋鎖一起使用。
9)本地軟中斷的禁止
方法1:
由于軟中斷是在硬件中斷處理程序結(jié)束時(shí)開始運(yùn)行的,所以最簡單的方式是禁止那個(gè)CPU上的中斷。
因?yàn)闆]有中斷處理例程被激活,故軟中斷就沒有機(jī)會(huì)運(yùn)行。
方法2:
通過操縱當(dāng)前thread_info描述符preempt_count字段中存放的軟中斷計(jì)數(shù)器,可以在本地CPU上激活
或禁止軟中斷。因?yàn)閮?nèi)核有時(shí)只需要禁止軟中斷而不禁止中斷。
評(píng)論
查看更多