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