為什麼linux 核心裡面很多**為了處理race condition(競爭條件),都加上了諸如cli sti這樣的開關中斷指令,這個問題貌似很不值得一提。在wait_on_buffer函式(如下**所示)中,開關中斷僅僅就是為了避免競爭條件和中斷對臨界**的干擾?
static _inline void wait_on_buffer(struct buffer_head * bh)
先還是來看看趙博的解釋吧:
當進入可能引起競爭條件的**區時,核心中就會用cli指令來關閉對外部中斷的響應,而在執行完競爭**區時核心就會執行sti指令已重新允許cpu響應外部中斷。
在繼續**之前,我覺得有必要在兩個問題上達成共識,呵呵,比較嚴肅的說法。
1、在wait_on_buffer (包括其它同樣有開關中斷指令的程式**) 它們都屬於核心**,也就是說當前這個程序是在核心態執行的。
2、核心態的程序不能搶占。
關於第一點,其實是很明白的。其它不說,就舉兩個例證:其一,我們執行sti這種特權指令,這個只能是核心態程序執行,不是一般使用者許可權就能執行的!要是隨隨便便是個程序都執行,可能系統很早就癱了;其二,那就是我們讀的**都是核心**,所以這個就是核心**,有點強詞奪理......
關於第二點,我想表達的意思是如果我們正在執行wait_on_buffer時,即使是沒有關中斷,我們也不會跳到其它程序,當然也不會有其他程序恰好修改了這個buffer中的屬性。因為核心是非搶占的!比如這裡的do_timer:
if (!cpl)
return; // 對於超級使用者程式,不依賴counter 值進行排程。
schedule ();
大家可以看到如果是核心**執行do_timer的話,他直接會返回,而不會執行任務切換!
所以我們可以總結下,程序執行wait_on_buffer時,是處於核心態,即使是沒有關閉中斷,不會排程到其它程序執行。唯一能干擾這種沒有關閉中斷的"裸等"只是一些其他的中斷。但是就是為了防止這些其它的中斷可能會改變臨界區的一些關鍵變數,我們還是要關掉中斷以防萬一。
有同志不解,因為他沒有在其他中斷中發現可能會修改buffer從而導致臨界區異常的**,所以覺得linux這樣寫不太妥。還是用趙博的一句話解釋吧:
在這方面不能就事論事。如果有乙個中斷會修改呢?核心程式設計者總不能老是牽掛這方面的問題。
單例雙重檢查引發的資源競爭 資料競爭
最近在寫golang 使用go編譯器的race分析工具,提公升以下 有資源競爭的問題 1 type memcache struct45 var memcacheinstance memcache 6var memcachecreatemutex sync.mutex 78 func getmemca...
共享全域性變數的資源競爭
共享全域性變數的資源競爭 import threading import time num 0def demo1 nums global num for i in range nums num 1print demo1 num d num defdemo2 nums global num for i...
網絡卡設定資源衝突處理方法
網絡卡設定資源衝突處理方法 網絡卡非常容易與其它裝置發生資源衝突,尤其是在系統中安裝有多隻介面卡的情況下,資源衝突常採用以下幾種方法處理。方法一 在上述 網絡卡屬性 視窗 資源 標籤的 資源型別 列表中選定發生衝突的 資源 按 更改設定 按鈕,更改發生衝突的irq中斷號或i o位址 方法二 早期網絡...