[LINUX]linux進程調度與中斷處理

linux進程調度與中斷處理:
簡單起見,只先看單核cpu的場景。

  • ①在linux內核中,每一個進程都有對應的進程上下文數據結構,其中存儲了本進程相關的屬性信息、運行時的狀態信息以及對應的u區表、用戶棧、內核棧等等一切和進程運行有關的所有的信息。類似於進程的身份證一樣。其中最最主要的數據字段是:進程狀態,分爲用戶態運行中、內核態運行中、睡眠狀態,和就緒狀態,前兩個看名字就理解了,睡眠狀態表示進程處於休眠態,不進入進程調度隊列,當且僅當某個條件滿足之後,纔會被喚醒,喚醒後也不是立即執行而是進入就緒狀態,意思是已經做好所有被調度的準備,會進入調度隊列中。所
    以,進程的調度是有專門的調度程序來實現的,裏面會根據優先級等調度策略實現進程的分時調度功能(linux實際上核心功能就是多進程分時調度的系統);
  • ②對於單cpu,內核同一個時間點只會運行一個進程,可能是在用戶態,也可能是在內核態,但有且僅有一個在運行,這有一個非常大的好處,即可以防止併發導致的條件競爭問題,當進程運行計時器到點了,或者由於一些IO操作、wait其他進程操作等進入睡眠狀態,則內核會進行進程的上下文切換,去調度另一個進程來執行,前者(計時器滿了),只可能發生在用戶態,後者,進入睡眠則只可能發生在內核態,原因是爲了避免全局數據在切換過程中發生異常,內核態的操作被設計成“原子操作”,即如果一個進程運行在內核態,那麼無法被進程切換,即便其執行時間計數器已經到了,這樣做的好處是可以很好的保持一些全局數據的一致性,避免由於進程的來回切換導致數據被不符合預期的破壞掉;
  • ③進程之間的同步:進程之間雖然沒有條件競爭(同一時間只有一個進程執行),但是仍然可能有同步的需求,即可能進程1運行到某個I/O後進入睡眠,這個時候其實我們並不期望進程2運行,我們可能希望進程2等進程1的I/O完畢後再運行。這種需要同步的場景,仍然需要用到條件變量(即類似鎖的概念),當某個條件沒有滿足時進入睡眠,不佔用cpu資源,直到這個條件被滿足才喚醒。cpu硬件提供的這種睡眠、喚醒的機制,很大程度上提升了程序的可能性,系統的吞吐量大大提升(如果沒有這種機制,可能就會需要輪詢的去檢查某個變量了,佔用cpu時間、佔用進程上下文切換等消耗)。④中斷處理程序:內核還有一些中斷機制,來處理一些“臨時緊急任務”,中斷本質上就是突然來了一個高優先級的任務,這個時候臨時的停止手頭工作,先到預設的中斷處理程序進行處理,處理完畢後再返回,之所以稱之爲中斷,而不是任務搶佔,是因爲中斷是硬件提供的一種機制(提供臨時停止+保留當前現場+恢復之前的執行的功能),但本質上就是高優先級的任務搶佔。需要注意的是中斷本身並不導致進程的切換,最多是執行態的切換,例如一個系統調用,我們可以觸發一個軟中斷,類似於一個更高優先級的任務,內核處理該中斷的處理函數就是system_call,從而實現了從用戶態到內核態的切換。中斷執行過程其實類似於切換進程的過程,如果不是程序員手動觸發的中斷,比如系統調用,其他的中斷很有可能導致之前的進程上下文中的一些數據被中斷處理程序訪問到,或者被修改,導致數據一致性問題,這個時候,提供的是臨界區提權的方案,即當進入到某些臨界區的時候,會將進程的執行優先級提升,以屏蔽中斷(中斷由於優先級不比當前進程高,會在隊列中等待)當退出臨界區的時候,恢復原來的優先級,中斷處理再執行。但是這個過程實際上會造成中斷處理的延遲(中斷其實非常多的),會影響系統的吞吐量,所以臨界區要儘量的最小化。
發佈了166 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章