從使用者態到核心態切換可以通過三種方式,或者說會導致從使用者態切換到核心態的操作:
外圍裝置中斷:外圍裝置完成使用者請求的操作之後,會向cpu發出中斷訊號,這時cpu會轉去處理對應的中斷處理程式。
當發生使用者態到核心態的切換時,會發生如下過程(本質上是從「使用者程式」切換到「核心程式」)
而之後從核心態返回使用者態時,又會進行類似的工作。
使用者態和核心態之間的切換有一定的開銷,如果頻繁發生切換勢必會帶來很大的開銷,所以要想盡一切辦法來減少切換。這也是面試常考的問題。
3.1 減少執行緒切換
因為執行緒的切換會導致使用者態和核心態之間的切換,所以減少執行緒切換也會減少使用者態和核心態之間的切換。那麼如何減少執行緒切換呢?
3.2 乙個面試問題
i/o 頻繁發生核心態和使用者態切換,怎麼解決。
首先要同意這個說法,即i/o會導致系統呼叫,從而導致核心態和使用者態之間的切換。因為對i/o裝置的操作是發生在核心態。那如何減少因為i/o導致的系統呼叫呢?答案是:使使用者程序緩衝區。下面解釋一下原因
使用者程序緩衝區
你看一些程式在讀取檔案時,會先申請一塊記憶體陣列,稱為buffer,然後每次呼叫read,讀取設定位元組長度的資料,寫入buffer。之後的程式都是從buffer中獲取資料,當buffer使用完後,在進行下一次呼叫,填充buffer。所以說:使用者緩衝區的目的就是是為了減少系統呼叫次數,從而降低作業系統在使用者態與核心態切換所耗費的時間。除了在程序中設計緩衝區,核心也有自己的緩衝區。
核心快取區
當乙個使用者程序要從磁碟讀取資料時,核心一般不直接讀磁碟,而是將核心緩衝區中的資料複製到程序緩衝區中。但若是核心緩衝區中沒有資料,核心會把對資料塊的請求,加入到請求佇列,然後把程序掛起,為其它程序提供服務。等到資料已經讀取到核心緩衝區時,把核心緩衝區中的資料讀取到使用者程序中,才會通知程序,當然不同的io模型,在排程和使用核心緩衝區的方式上有所不同。
小結圖中的read,write和sync都是系統呼叫。read是把資料從核心緩衝區複製到程序緩衝區。write是把程序緩衝區複製到核心緩衝區。當然,write並不一定導致核心的快取同步動作sync,比如os可能會把核心緩衝區的資料積累到一定量後,再一次性同步到磁碟中。這也就是為什麼斷電有時會導致資料丟失。所以說核心緩衝區,可以在os級別,提高磁碟io效率,優化磁碟寫操作。
為什麼加鎖和釋放鎖會導致上下文切換
synchronized是通過物件內部的乙個叫做監視器鎖(monitor)來實現的。但是監視器鎖本質又是依賴於底層的作業系統的mutex lock來實現的。但是由於使用mutex lock需要將當前執行緒掛起並從使用者態切換到核心態來執行,這種切換的代價是非常昂貴的因此,這種依賴於作業系統mutex lock所實現的鎖我們稱之為「重量級鎖」。
(上述說法不是很準確,應該不是每種鎖都是切換到核心態,這點我不太確認)
mutex和spin lock的區別
mutex和spin lock的區別和應用(sleep-waiting和busy-waiting的區別)2011-10-19 11:43
而自旋鎖spin lock是busy-waiting。就是說當沒有可用的鎖時,就一直忙等待並不停的進行鎖請求,直到得到這個鎖為止。這個過程中cpu始終處於忙狀態,不能做別的任務。
例如在乙個雙核的機器上有兩個執行緒(執行緒a和執行緒b),它們分別執行在core0 和core1上。 用spin-lock,coer0上的執行緒就會始終占用cpu。
另外乙個值得注意的細節是spin lock耗費了更多的user time。這就是因為兩個執行緒分別執行在兩個核上,大部分時間只有乙個執行緒能拿到鎖,所以另乙個執行緒就一直在它執行的core上進行忙等待,cpu佔用率一直是100%;而mutex則不同,當對鎖的請求失敗後上下文切換就會發生,這樣就能空出乙個核來進行別的運算任務了。(其實這種上下文切換對已經拿著鎖的那個執行緒效能也是有影響的,因為當該執行緒釋放該鎖時它需要通知作業系統去喚醒那些被阻塞的執行緒,這也是額外的開銷)
總結(1)mutex適合對鎖操作非常頻繁的場景,並且具有更好的適應性。儘管相比spin lock它會花費更多的開銷(主要是上下文切換),但是它能適合實際開發中複雜的應用場景,在保證一定效能的前提下提供更大的靈活度。
使用者態和核心態的切換
系統呼叫 比如fork 方法,直接fork出乙個執行緒 具體的底層實現是軟體中斷,下面會講 異常 當cpu在執行使用者空間的程式時,發生了異常,處理異常的話就必須在核心態進行處理,比如缺頁異常 外圍裝置的中斷 當進行檔案io操作完成後,硬體io裝置會向cpu發出乙個中斷訊號,如果這時候cpu正在執行...
核心態與使用者態切換
a.系統呼叫 這是使用者態程序主動要求切換到核心態的一種方式,使用者態程序通過系統呼叫申請使用作業系統提供的服務程式完成工作,比如前例中fork 實際上就是執行了乙個建立新程序的系統呼叫。而系統呼叫的機制其核心還是使用了作業系統為使用者特別開放的乙個中斷來實現,例如linux的int 80h中斷。b...
Linux使用者態切換核心態介紹
在linux系統中,所有中斷服務程式都屬於核心 如果乙個中斷產生時任務正在使用者 中執行,那麼該中斷就會引起cpu特權級從3級到0級的變化,此時cpu就會進行使用者態堆疊到核心態堆疊的切換操作。cpu會從當前任務的任務狀態段tss中取得新堆疊的段選擇符和偏移值。因為中斷服務程式在核心中,屬於0級特權...