㈠ 實時操作系統中說的搶占式和可剝奪內核是同一個意思嗎
是一個意思。抄
實時系統可分襲兩類:可搶占式(可剝奪。如VxWorks)和非搶占式(不可剝奪。如linux)系統。
通常,後者採用時間片輪詢方式調度,前者則嚴格按照優先順序調度。什麼意思呢?假設有兩個任務:高優先順序任務T1和低優先順序任務T2。
某一時刻,T2正在運行,沒有執行完,而T1就緒(比如在硬中斷里發生了事件需要響應)。此時,兩種內核的調度行為差別是:
——非搶占式內核:只有等T2執行完釋放CPU,T1才能運行;
——搶占式內核:退出就緒T1任務的中斷時就會產生調度行為,結果是T2被懸掛,T1立即得到執行。即:T1搶佔了(剝奪了)T1的CPU資源。
㈡ linux內核中造成並發執行的原因是什麼
linux中內核並發機制也就是同步機制產生的原因,總的來說可歸納為一下4點:
l 中斷——中斷幾乎可以在任何時刻非同步發生,也就可能隨時打斷當前正在執行的代碼。
2 睡眠及與用戶空間的同步——在內核執行的進程可能會睡眠,這就會喚醒調度程序,從而導致調度一個新的用戶進程執行。
3 對稱多處理——兩個或多個處理器可以同時執行代碼。
4內核搶占——因為內核具有搶占性,所以內核中的任務可能會被另一任務搶占(在2.6內核引進的新能力)。
㈢ linux環境下的進程調度演算法有哪些
第一部分: 實時調度演算法介紹
對於什麼是實時系統,POSIX 1003.b作了這樣的定義:指系統能夠在限定的響應時間內提供所需水平的服務。而一個由Donald Gillies提出的更加為大家接受的定義是:一個實時系統是指計算的正確性不僅取決於程序的邏輯正確性,也取決於結果產生的時間,如果系統的時間約束條件得不到滿足,將會發生系統出錯。
實時系統根據其對於實時性要求的不同,可以分為軟實時和硬實時兩種類型。硬實時系統指系統要有確保的最壞情況下的服務時間,即對於事件的響應時間的截止期限是無論如何都必須得到滿足。比如航天中的宇宙飛船的控制等就是現實中這樣的系統。其他的所有有實時特性的系統都可以稱之為軟實時系統。如果明確地來說,軟實時系統就是那些從統計的角度來說,一個任務(在下面的論述中,我們將對任務和進程不作區分)能夠得到有確保的處理時間,到達系統的事件也能夠在截止期限到來之前得到處理,但違反截止期限並不會帶來致命的錯誤,像實時多媒體系統就是一種軟實時系統。
一個計算機系統為了提供對於實時性的支持,它的操作系統必須對於CPU和其他資源進行有效的調度和管理。在多任務實時系統中,資源的調度和管理更加復雜。本文下面將先從分類的角度對各種實時任務調度演算法進行討論,然後研究普通的 Linux操作系統的進程調度以及各種實時Linux系統為了支持實時特性對普通Linux系統所做的改進。最後分析了將Linux操作系統應用於實時領域中時所出現的一些問題,並總結了各種實時Linux是如何解決這些問題的。
1. 實時CPU調度演算法分類
各種實時操作系統的實時調度演算法可以分為如下三種類別[Wang99][Gopalan01]:基於優先順序的調度演算法(Priority-driven scheling-PD)、基於CPU使用比例的共享式的調度演算法(Share-driven scheling-SD)、以及基於時間的進程調度演算法(Time-driven scheling-TD),下面對這三種調度演算法逐一進行介紹。
1.1. 基於優先順序的調度演算法
基於優先順序的調度演算法給每個進程分配一個優先順序,在每次進程調度時,調度器總是調度那個具有最高優先順序的任務來執行。根據不同的優先順序分配方法,基於優先順序的調度演算法可以分為如下兩種類型[Krishna01][Wang99]:
靜態優先順序調度演算法:
這種調度演算法給那些系統中得到運行的所有進程都靜態地分配一個優先順序。靜態優先順序的分配可以根據應用的屬性來進行,比如任務的周期,用戶優先順序,或者其它的預先確定的策略。RM(Rate-Monotonic)調度演算法是一種典型的靜態優先順序調度演算法,它根據任務的執行周期的長短來決定調度優先順序,那些具有小的執行周期的任務具有較高的優先順序。
動態優先順序調度演算法:
這種調度演算法根據任務的資源需求來動態地分配任務的優先順序,其目的就是在資源分配和調度時有更大的靈活性。非實時系統中就有很多這種調度演算法,比如短作業優先的調度演算法。在實時調度演算法中, EDF演算法是使用最多的一種動態優先順序調度演算法,該演算法給就緒隊列中的各個任務根據它們的截止期限(Deadline)來分配優先順序,具有最近的截止期限的任務具有最高的優先順序。
1.2. 基於比例共享調度演算法
雖然基於優先順序的調度演算法簡單而有效,但這種調度演算法提供的是一種硬實時的調度,在很多情況下並不適合使用這種調度演算法:比如象實時多媒體會議系統這樣的軟實時應用。對於這種軟實時應用,使用一種比例共享式的資源調度演算法(SD演算法)更為適合。
比例共享調度演算法指基於CPU使用比例的共享式的調度演算法,其基本思想就是按照一定的權重(比例)對一組需要調度的任務進行調度,讓它們的執行時間與它們的權重完全成正比。
我們可以通過兩種方法來實現比例共享調度演算法[Nieh01]:第一種方法是調節各個就緒進程出現在調度隊列隊首的頻率,並調度隊首的進程執行;第二種做法就是逐次調度就緒隊列中的各個進程投入運行,但根據分配的權重調節分配個每個進程的運行時間片。
比例共享調度演算法可以分為以下幾個類別:輪轉法、公平共享、公平隊列、彩票調度法(Lottery)等。
比例共享調度演算法的一個問題就是它沒有定義任何優先順序的概念;所有的任務都根據它們申請的比例共享CPU資源,當系統處於過載狀態時,所有的任務的執行都會按比例地變慢。所以為了保證系統中實時進程能夠獲得一定的CPU處理時間,一般採用一種動態調節進程權重的方法。
1.3. 基於時間的進程調度演算法
對於那些具有穩定、已知輸入的簡單系統,可以使用時間驅動(Time-driven:TD)的調度演算法,它能夠為數據處理提供很好的預測性。這種調度演算法本質上是一種設計時就確定下來的離線的靜態調度方法。在系統的設計階段,在明確系統中所有的處理情況下,對於各個任務的開始、切換、以及結束時間等就事先做出明確的安排和設計。這種調度演算法適合於那些很小的嵌入式系統、自控系統、感測器等應用環境。
這種調度演算法的優點是任務的執行有很好的可預測性,但最大的缺點是缺乏靈活性,並且會出現有任務需要被執行而CPU卻保持空閑的情況。
2. 通用Linux系統中的CPU調度
通用Linux系統支持實時和非實時兩種進程,實時進程相對於普通進程具有絕對的優先順序。對應地,實時進程採用SCHED_FIFO或者SCHED_RR調度策略,普通的進程採用SCHED_OTHER調度策略。
在調度演算法的實現上,Linux中的每個任務有四個與調度相關的參數,它們是rt_priority、policy、priority(nice)、counter。調度程序根據這四個參數進行進程調度。
在SCHED_OTHER 調度策略中,調度器總是選擇那個priority+counter值最大的進程來調度執行。從邏輯上分析,SCHED_OTHER調度策略存在著調度周期(epoch),在每一個調度周期中,一個進程的priority和counter值的大小影響了當前時刻應該調度哪一個進程來執行,其中 priority是一個固定不變的值,在進程創建時就已經確定,它代表了該進程的優先順序,也代表這該進程在每一個調度周期中能夠得到的時間片的多少; counter是一個動態變化的值,它反映了一個進程在當前的調度周期中還剩下的時間片。在每一個調度周期的開始,priority的值被賦給 counter,然後每次該進程被調度執行時,counter值都減少。當counter值為零時,該進程用完自己在本調度周期中的時間片,不再參與本調度周期的進程調度。當所有進程的時間片都用完時,一個調度周期結束,然後周而復始。另外可以看出Linux系統中的調度周期不是靜態的,它是一個動態變化的量,比如處於可運行狀態的進程的多少和它們priority值都可以影響一個epoch的長短。值得注意的一點是,在2.4以上的內核中, priority被nice所取代,但二者作用類似。
可見SCHED_OTHER調度策略本質上是一種比例共享的調度策略,它的這種設計方法能夠保證進程調度時的公平性--一個低優先順序的進程在每一個epoch中也會得到自己應得的那些CPU執行時間,另外它也提供了不同進程的優先順序區分,具有高priority值的進程能夠獲得更多的執行時間。
對於實時進程來說,它們使用的是基於實時優先順序rt_priority的優先順序調度策略,但根據不同的調度策略,同一實時優先順序的進程之間的調度方法有所不同:
SCHED_FIFO:不同的進程根據靜態優先順序進行排隊,然後在同一優先順序的隊列中,誰先准備好運行就先調度誰,並且正在運行的進程不會被終止直到以下情況發生:1.被有更高優先順序的進程所強佔CPU;2.自己因為資源請求而阻塞;3.自己主動放棄CPU(調用sched_yield);
SCHED_RR:這種調度策略跟上面的SCHED_FIFO一模一樣,除了它給每個進程分配一個時間片,時間片到了正在執行的進程就放棄執行;時間片的長度可以通過sched_rr_get_interval調用得到;
由於Linux系統本身是一個面向桌面的系統,所以將它應用於實時應用中時存在如下的一些問題:
Linux系統中的調度單位為10ms,所以它不能夠提供精確的定時;
當一個進程調用系統調用進入內核態運行時,它是不可被搶占的;
Linux內核實現中使用了大量的封中斷操作會造成中斷的丟失;
由於使用虛擬內存技術,當發生頁出錯時,需要從硬碟中讀取交換數據,但硬碟讀寫由於存儲位置的隨機性會導致隨機的讀寫時間,這在某些情況下會影響一些實時任務的截止期限;
雖然Linux進程調度也支持實時優先順序,但缺乏有效的實時任務的調度機制和調度演算法;它的網路子系統的協議處理和其它設備的中斷處理都沒有與它對應的進程的調度關聯起來,並且它們自身也沒有明確的調度機制;
3. 各種實時Linux系統
3.1. RT-Linux和RTAI
RT -Linux是新墨西哥科技大學(New Mexico Institute of Technology)的研究成果[RTLinuxWeb][Barabanov97]。它的基本思想是,為了在Linux系統中提供對於硬實時的支持,它實現了一個微內核的小的實時操作系統(我們也稱之為RT-Linux的實時子系統),而將普通Linux系統作為一個該操作系統中的一個低優先順序的任務來運行。另外普通Linux系統中的任務可以通過FIFO和實時任務進行通信。RT-Linux的框架如圖 1所示:
圖 1 RT-Linux結構
RT -Linux的關鍵技術是通過軟體來模擬硬體的中斷控制器。當Linux系統要封鎖CPU的中斷時時,RT-Linux中的實時子系統會截取到這個請求,把它記錄下來,而實際上並不真正封鎖硬體中斷,這樣就避免了由於封中斷所造成的系統在一段時間沒有響應的情況,從而提高了實時性。當有硬體中斷到來時, RT-Linux截取該中斷,並判斷是否有實時子系統中的中斷常式來處理還是傳遞給普通的Linux內核進行處理。另外,普通Linux系統中的最小定時精度由系統中的實時時鍾的頻率決定,一般Linux系統將該時鍾設置為每秒來100個時鍾中斷,所以Linux系統中一般的定時精度為 10ms,即時鍾周期是10ms,而RT-Linux通過將系統的實時時鍾設置為單次觸發狀態,可以提供十幾個微秒級的調度粒度。
RT-Linux實時子系統中的任務調度可以採用RM、EDF等優先順序驅動的演算法,也可以採用其他調度演算法。
RT -Linux對於那些在重負荷下工作的專有系統來說,確實是一個不錯的選擇,但他僅僅提供了對於CPU資源的調度;並且實時系統和普通Linux系統關系不是十分密切,這樣的話,開發人員不能充分利用Linux系統中已經實現的功能,如協議棧等。所以RT-Linux適合與工業控制等實時任務功能簡單,並且有硬實時要求的環境中,但如果要應用與多媒體處理中還需要做大量的工作。
義大利的RTAI( Real-Time Application Interface )源於RT-Linux,它在設計思想上和RT-Linux完全相同。它當初設計目的是為了解決RT-Linux難於在不同Linux版本之間難於移植的問題,為此,RTAI在 Linux 上定義了一個實時硬體抽象層,實時任務通過這個抽象層提供的介面和Linux系統進行交互,這樣在給Linux內核中增加實時支持時可以盡可能少地修改 Linux的內核源代碼。
3.2. Kurt-Linux
Kurt -Linux由Kansas大學開發,它可以提供微秒級的實時精度[KurtWeb] [Srinivasan]。不同於RT-Linux單獨實現一個實時內核的做法,Kurt -Linux是在通用Linux系統的基礎上實現的,它也是第一個可以使用普通Linux系統調用的基於Linux的實時系統。
Kurt-Linux將系統分為三種狀態:正常態、實時態和混合態,在正常態時它採用普通的Linux的調度策略,在實時態只運行實時任務,在混合態實時和非實時任務都可以執行;實時態可以用於對於實時性要求比較嚴格的情況。
為了提高Linux系統的實時特性,必須提高系統所支持的時鍾精度。但如果僅僅簡單地提高時鍾頻率,會引起調度負載的增加,從而嚴重降低系統的性能。為了解決這個矛盾, Kurt-Linux採用UTIME所使用的提高Linux系統中的時鍾精度的方法[UTIMEWeb]:它將時鍾晶元設置為單次觸發狀態(One shot mode),即每次給時鍾晶元設置一個超時時間,然後到該超時事件發生時在時鍾中斷處理程序中再次根據需要給時鍾晶元設置一個超時時間。它的基本思想是一個精確的定時意味著我們需要時鍾中斷在我們需要的一個比較精確的時間發生,但並非一定需要系統時鍾頻率達到此精度。它利用CPU的時鍾計數器TSC (Time Stamp Counter)來提供精度可達CPU主頻的時間精度。
對於實時任務的調度,Kurt-Linux採用基於時間(TD)的靜態的實時CPU調度演算法。實時任務在設計階段就需要明確地說明它們實時事件要發生的時間。這種調度演算法對於那些循環執行的任務能夠取得較好的調度效果。
Kurt -Linux相對於RT-Linux的一個優點就是可以使用Linux系統自身的系統調用,它本來被設計用於提供對硬實時的支持,但由於它在實現上只是簡單的將Linux調度器用一個簡單的時間驅動的調度器所取代,所以它的實時進程的調度很容易受到其它非實時任務的影響,從而在有的情況下會發生實時任務的截止期限不能滿足的情況,所以也被稱作嚴格實時系統(Firm Real-time)。目前基於Kurt-Linux的應用有:ARTS(ATM Reference Traffic System)、多媒體播放軟體等。另外Kurt-Linux所採用的這種方法需要頻繁地對時鍾晶元進行編程設置。
3.3. RED-Linux
RED -Linux是加州大學Irvine分校開發的實時Linux系統[REDWeb][ Wang99],它將對實時調度的支持和Linux很好地實現在同一個操作系統內核中。它同時支持三種類型的調度演算法,即:Time-Driven、 Priority-Dirven、Share-Driven。
為了提高系統的調度粒度,RED-Linux從RT-Linux那兒借鑒了軟體模擬中斷管理器的機制,並且提高了時鍾中斷頻率。當有硬體中斷到來時,RED-Linux的中斷模擬程序僅僅是簡單地將到來的中斷放到一個隊列中進行排隊,並不執行真正的中斷處理程序。
另外為了解決Linux進程在內核態不能被搶占的問題, RED-Linux在Linux內核的很多函數中插入了搶占點原語,使得進程在內核態時,也可以在一定程度上被搶占。通過這種方法提高了內核的實時特性。
RED-Linux的設計目標就是提供一個可以支持各種調度演算法的通用的調度框架,該系統給每個任務增加了如下幾項屬性,並將它們作為進程調度的依據:
Priority:作業的優先順序;
Start-Time:作業的開始時間;
Finish-Time:作業的結束時間;
Budget:作業在運行期間所要使用的資源的多少;
通過調整這些屬性的取值及調度程序按照什麼樣的優先順序來使用這些屬性值,幾乎可以實現所有的調度演算法。這樣的話,可以將三種不同的調度演算法無縫、統一地結合到了一起。
㈣ 從2.x到4.x,Linux內核這十年經歷了哪些重要變革
Linux內核現在已經進入4.x時代了,但是據說從版本2.6升到3.0,以及3.19升到4.0這之間都沒什麼太大的變革。事實如此嗎?內核版本間的區別有多大?
說實話,這個問題挺大的。Linux內核的2.6 時代跨度非常大,從2.6.1 (2003年12月發布) 到 2.6.39(2011年5月發布),跨越了39 個大版本。3.0(原計劃的2.6.40,2011年7月發布) 到 3.19(2015年2月發布),經歷了20個版本。4.0(2015年4月發布)到4.2(2015年8月底發布),又有3個版本。
總的來說,從進入2.6之後,每個大版本跨度開發時間大概是 2 - 3 個月。2.6.x , 3.x, 4.x,數字的遞進並沒有非常根本性,引人注目的大變化,但每個大版本中都有一些或大或小的功能改變。主版本號只是一個數字而已。不過要直接從 2.6.x 升級 到 3.x, 乃至 4.x,隨著時間間隔增大,出問題的機率當然大很多。
個人覺得 Linux 真正走入嚴肅級別的高穩定性,高可用性,高可伸縮性的工業級別內核大概是在 2003 年之後吧!一是隨著互聯網的迅速普及,更多的人使用、參與開發。二是社區經過11年發展,已經慢慢摸索出一套很穩定的協同開發模式,一個重要的特點是社區 開始使用版本管理工具進行管理,脫離了之前純粹手工(或一些輔助的簡陋工具)處理代碼郵件的方式,大大加快了開發的速度和力度。
因此,本文匯總分析一下從 2.6.12 (2005年6月發布,也就是社區開始使用 git 進行管理後的第一個大版本),到 4.2 (2015年8月發布)這中間共 51個大版本 ,時間跨度 10年 的主要大模塊的一些重要的變革。
1.搶占支持(preemption): 2.6 時代開始支持(具體時間難考,是在 2.5 這個奇數版本中引入,可看此文章[1],關於 Linux 版本規則,可看我文章[2])。
可搶占性,對一個系統的調度延時具有重要意義。2.6 之前,一個進程進入內核態後,別的進程無法搶占,只能等其完成或退出內核態時才能搶占,這帶來嚴重的延時問題,2.6 開始支持內核態搶占。
2.普通進程調度器(SCHED_OTHER)之糾結進化史
Linux一開始,普通進程和實時進程都是基於優先順序的一個調度器,實時進程支持 100 個優先順序,普通進程是優先順序小於實時進程的一個靜態優先順序,所有普通進程創建時都是默認此優先順序,但可通過 nice() 介面調整動態優先順序(共40個)。實時進程的調度器比較簡單,而普通進程的調度器,則歷經變遷[3]:
(1) O(1) 調度器:2.6 時代開始支持(2002年引入)。顧名思義,此調度器為O(1)時間復雜度。該調度器以修正之間的O(n) 時間復雜度調度器,以解決擴展性問題。為每一個動態優先順序維護隊列,從而能在常數時間內選舉下一個進程來執行。
㈤ 在 2.4 版本的 linux 內核中,內核任務可以被搶占嗎
UNIX採用搶占式內核,Linux採用非搶占式內核
內核搶占(可搶占式內核):即當進程位於內核空間時,有一個更高優先順序的任務出現時,如果當前內核允許搶占,則可以將當前任務掛起,執行優先順序更高的進程。
非搶占式內核:高優先順序的進程不能中止正在內核中運行的低優先順序的進程而搶佔CPU運行。進程一旦處於核心態(例如用戶進程執行系統調用),則除非進程自願放棄CPU,否則該進程將一直運行下去,直至完成或退出內核
搶占式內核的意義:首先,這是將Linux應用於實時系統所必需的。實時系統對響應時間有嚴格的限定,當一個實時進程被實時設備的硬體中斷喚醒後,它應在限定的時間內被調度執行。而Linux不能滿足這一要求,因為Linux的內核是不可搶占的,不能確定系統在內核中的停留時間。事實上當內核執行長的系統調用時,實時進程要等到內核中運行的進程退出內核才能被調度,由此產生的響應延遲,在如今的硬體條件下,會長達100ms級。這對於那些要求高實時響應的系統是不能接受的。而可搶占的內核不僅對Linux的實時應用至關重要,而且能解決Linux對多媒體(video, audio)等要求低延遲的應用支持不夠好的缺陷。
頂
㈥ linux進程調度的三種策略是什麼
linux內核的三種主要調度策略:
1,SCHED_OTHER 分時調度策略,
2,SCHED_FIFO實時調度策略,先到先服務
3,SCHED_RR實時調度策略,時間片輪轉
實時進程將得到優先調用,實時進程根據實時優先順序決定調度權值。分時進程則通過nice和counter值決定權值,nice越小,counter越大,被調度的概率越大,也就是曾經使用了cpu最少的進程將會得到優先調度。
SHCED_RR和SCHED_FIFO的不同:
當採用SHCED_RR策略的進程的時間片用完,系統將重新分配時間片,並置於就緒隊列尾。放在隊列尾保證了所有具有相同優先順序的RR任務的調度公平。
SCHED_FIFO一旦佔用cpu則一直運行。一直運行直到有更高優先順序任務到達或自己放棄。
如果有相同優先順序的實時進程(根據優先順序計算的調度權值是一樣的)已經准備好,FIFO時必須等待該進程主動放棄後才可以運行這個優先順序相同的任務。而RR可以讓每個任務都執行一段時間。
相同點:
RR和FIFO都只用於實時任務。
創建時優先順序大於0(1-99)。
按照可搶占優先順序調度演算法進行。
就緒態的實時任務立即搶占非實時任務。
所有任務都採用linux分時調度策略時:
1,創建任務指定採用分時調度策略,並指定優先順序nice值(-20~19)。
2,將根據每個任務的nice值確定在cpu上的執行時間(counter)。
3,如果沒有等待資源,則將該任務加入到就緒隊列中。
4,調度程序遍歷就緒隊列中的任務,通過對每個任務動態優先順序的計算權值(counter+20-nice)結果,選擇計算結果最大的一個去運行,當這個時間片用完後(counter減至0)或者主動放棄cpu時,該任務將被放在就緒隊列末尾(時間片用完)或等待隊列(因等待資源而放棄cpu)中。
5,此時調度程序重復上面計算過程,轉到第4步。
6,當調度程序發現所有就緒任務計算所得的權值都為不大於0時,重復第2步。
所有任務都採用FIFO時:
1,創建進程時指定採用FIFO,並設置實時優先順序rt_priority(1-99)。
2,如果沒有等待資源,則將該任務加入到就緒隊列中。
3,調度程序遍歷就緒隊列,根據實時優先順序計算調度權值(1000+rt_priority),選擇權值最高的任務使用cpu,該FIFO任務將一直佔有cpu直到有優先順序更高的任務就緒(即使優先順序相同也不行)或者主動放棄(等待資源)。
4,調度程序發現有優先順序更高的任務到達(高優先順序任務可能被中斷或定時器任務喚醒,再或被當前運行的任務喚醒,等等),則調度程序立即在當前任務堆棧中保存當前cpu寄存器的所有數據,重新從高優先順序任務的堆棧中載入寄存器數據到cpu,此時高優先順序的任務開始運行。重復第3步。
5,如果當前任務因等待資源而主動放棄cpu使用權,則該任務將從就緒隊列中刪除,加入等待隊列,此時重復第3步。
所有任務都採用RR調度策略時:
1,創建任務時指定調度參數為RR,並設置任務的實時優先順序和nice值(nice值將會轉換為該任務的時間片的長度)。
2,如果沒有等待資源,則將該任務加入到就緒隊列中。
3,調度程序遍歷就緒隊列,根據實時優先順序計算調度權值(1000+rt_priority),選擇權值最高的任務使用cpu。
4,如果就緒隊列中的RR任務時間片為0,則會根據nice值設置該任務的時間片,同時將該任務放入就緒隊列的末尾。重復步驟3。
5,當前任務由於等待資源而主動退出cpu,則其加入等待隊列中。重復步驟3。
系統中既有分時調度,又有時間片輪轉調度和先進先出調度:
1,RR調度和FIFO調度的進程屬於實時進程,以分時調度的進程是非實時進程。
2,當實時進程准備就緒後,如果當前cpu正在運行非實時進程,則實時進程立即搶占非實時進程。
3,RR進程和FIFO進程都採用實時優先順序做為調度的權值標准,RR是FIFO的一個延伸。FIFO時,如果兩個進程的優先順序一樣,則這兩個優先順序一樣的進程具體執行哪一個是由其在隊列中的未知決定的,這樣導致一些不公正性(優先順序是一樣的,為什麼要讓你一直運行?),如果將兩個優先順序一樣的任務的調度策略都設為RR,則保證了這兩個任務可以循環執行,保證了公平。
Ingo Molnar-實時補丁
為了能並入主流內核,Ingo Molnar的實時補丁也採用了非常靈活的策略,它支持四種搶占模式:
1.No Forced Preemption (Server),這種模式等同於沒有使能搶占選項的標准內核,主要適用於科學計算等伺服器環境。
2.Voluntary Kernel Preemption (Desktop),這種模式使能了自願搶占,但仍然失效搶占內核選項,它通過增加搶占點縮減了搶占延遲,因此適用於一些需要較好的響應性的環境,如桌面環境,當然這種好的響應性是以犧牲一些吞吐率為代價的。
3.Preemptible Kernel (Low-Latency Desktop),這種模式既包含了自願搶占,又使能了可搶占內核選項,因此有很好的響應延遲,實際上在一定程度上已經達到了軟實時性。它主要適用於桌面和一些嵌入式系統,但是吞吐率比模式2更低。
4.Complete Preemption (Real-Time),這種模式使能了所有實時功能,因此完全能夠滿足軟實時需求,它適用於延遲要求為100微秒或稍低的實時系統。
實現實時是以犧牲系統的吞吐率為代價的,因此實時性越好,系統吞吐率就越低。
㈦ Linux內核設計與實現的目錄
譯者序
序言
前言
作者簡介
第1章Linux內核簡介1
1.1Unix的歷史1
1.2追尋Linus足跡:Linux簡介2
1.3操作系統和內核簡介3
1.4Linux內核和傳統Unix內核的比較5
1.5Linux內核版本7
1.6Linux內核開發者社區8
1.7小結8
第2章從內核出發10
2.1獲取內核源碼10
2.1.1使用Git10
2.1.1安裝內核源代碼10
2.1.3使用補丁11
2.2內核源碼樹11
2.3編譯內核12
2.3.1配置內核12
2.3.2減少編譯的垃圾信息14
2.3.3衍生多個編譯作業 14
2.3.4安裝新內核14
2.4內核開發的特點15
2.4.1無libc庫抑或無標准頭文件15
2.4.2GNU C16
2.4.3沒有內存保護機制18
2.4.4不要輕易在內核中使用浮點數18
2.4.5容積小而固定的棧18
2.4.6同步和並發18
2.4.7可移植性的重要性19
2.5小結19
第3章進程管理20
3.1進程20
3.2進程描述符及任務結構 21
3.2.1分配進程描述符22
3.2.2進程描述符的存放23
3.2.3進程狀態23
3.2.4設置當前進程狀態25
3.2.5進程上下文25
3.2.6進程家族樹25
3.3進程創建26
3.3.1寫時拷貝27
3.3.2fork()27
3.3.3vfork()28
3.4線程在Linux中的實現28
3.4.1創建線程29
3.4.2內核線程30
3.5進程終結31
3.5.1刪除進程描述符32
3.5.2孤兒進程造成的進退維谷32
3.6小結34
第4章進程調度35
4.1多任務35
4.2Linux 的進程調度36
4.3策略36
4.3.1I/O消耗型和處理器消耗型的進程36
4.3.2進程優先順序37
4.3.3時間片38
4.3.4調度策略的活動38
4.4Linux調度演算法39
4.4.1調度器類39
4.4.2Unix 系統中的進程調度40
4.4.3公平調度41
4.5Linux調度的實現42
4.5.1時間記賬42
4.5.2進程選擇44
4.5.3調度器入口48
4.5.4睡眠和喚醒49
4.6搶占和上下文切換51
4.6.1用戶搶佔53
4.6.2內核搶佔53
4.7實時調度策略54
4.8與調度相關的系統調用54
4.8.1與調度策略和優先順序相關的系統調用55
4.8.2與處理器綁定有關的系統調用55
4.8.3放棄處理器時間56
4.9小結56
第5章系統調用57
5.1與內核通信57
5.2API、POSIX和C庫57
5.3系統調用58
5.3.1系統調用號59
5.3.2系統調用的性能59
5.4系統調用處理程序60
5.4.1指定恰當的系統調用60
5.4.2參數傳遞60
5.5系統調用的實現61
5.5.1實現系統調用61
5.5.2參數驗證62
5.6系統調用上下文64
5.6.1綁定一個系統調用的最後步驟65
5.6.2從用戶空間訪問系統調用67
5.6.3為什麼不通過系統調用的方式實現68
5.7小結68
第6章內核數據結構69
6.1鏈表69
6.1.1單向鏈表和雙向鏈表69
6.1.2環形鏈表70
6.1.3沿鏈表移動71
6.1.4Linux 內核中的實現71
6.1.5操作鏈表73
6.1.6遍歷鏈表75
6.2隊列78
6.2.1kfifo79
6.2.2創建隊列79
6.2.3推入隊列數據79
6.2.4摘取隊列數據80
6.2.5獲取隊列長度80
6.2.6重置和撤銷隊列80
6.2.7隊列使用舉例 81
6.3映射 81
6.3.1初始化一個idr82
6.3.2分配一個新的UID82
6.3.3查找UID83
6.3.4刪除UID84
6.3.5撤銷idr84
6.4二叉樹84
6.4.1二叉搜索樹84
6.4.2自平衡二叉搜索樹 85
6.5數據結構以及選擇 87
6.6演算法復雜度88
6.6.1演算法88
6.6.2大o 符號88
6.6.3大θ符號89
6.6.4時間復雜度89
6.7小結 90
第7章中斷和中斷處理91
7.1中斷91
7.2中斷處理程序92
7.3上半部與下半部的對比93
7.4注冊中斷處理程序93
7.4.1中斷處理程序標志94
7.4.2一個中斷例子95
7.4.3釋放中斷處理程序95
7.5編寫中斷處理程序96
7.5.1共享的中斷處理程序97
7.5.2中斷處理程序實例97
7.6中斷上下文99
7.7中斷處理機制的實現100
7.8/proc/interrupts102
7.9中斷控制103
7.9.1禁止和激活中斷103
7.9.2禁止指定中斷線105
7.9.3中斷系統的狀態105
7.10小結106
第8章下半部和推後執行的工作107
8.1下半部107
8.1.1為什麼要用下半部108
8.1.2下半部的環境108
8.2軟中斷110
8.2.1軟中斷的實現111
8.2.2使用軟中斷113
8.3tasklet114
8.3.1tasklet的實現114
8.3.2使用tasklet116
8.3.3老的BH機制119
8.4工作隊列120
8.4.1工作隊列的實現121
8.4.2使用工作隊列124
8.4.3老的任務隊列機制126
8.5下半部機制的選擇127
8.6在下半部之間加鎖128
8.7禁止下半部128
8.8小結129
第9章內核同步介紹131
9.1臨界區和競爭條件131
9.1.1為什麼我們需要保護132
9.1.2單個變數133
9.2加鎖134
9.2.1造成並發執行的原因135
9.2.2了解要保護些什麼136
9.3死鎖137
9.4爭用和擴展性138
9.5小結140
第10章內核同步方法141
10.1原子操作141
10.1.1原子整數操作142
10.1.264位原子操作144
10.1.3原子位操作145
10.2自旋鎖147
10.2.1自旋鎖方法148
10.2.2其他針對自旋鎖的操作149
10.2.3自旋鎖和下半部150
10.3讀-寫自旋鎖150
10.4信號量152
10.4.1計數信號量和二值信號量153
10.4.2創建和初始化信號量154
10.4.3使用信號量154
10.5讀-寫信號量155
10.6互斥體156
10.6.1信號量和互斥體158
10.6.2自旋鎖和互斥體158
10.7完成變數158
10.8BLK:大內核鎖159
10.9順序鎖160
10.10禁止搶佔161
10.11順序和屏障162
10.12小結165
第11章定時器和時間管理166
11.1內核中的時間概念166
11.2節拍率:HZ167
11.2.1理想的HZ值168
11.2.2高HZ的優勢169
11.2.3高HZ的劣勢169
11.3jiffies170
11.3.1jiffies的內部表示171
11.3.2jiffies 的回繞172
11.3.3用戶空間和HZ173
11.4硬時鍾和定時器174
11.4.1實時時鍾174
11.4.2系統定時器174
11.5時鍾中斷處理程序174
11.6實際時間176
11.7定時器178
11.7.1使用定時器178
11.7.2定時器競爭條件180
11.7.3實現定時器180
11.8延遲執行181
11.8.1忙等待181
11.8.2短延遲182
11.8.3schele_timeout()183
11.9小結185
第12章內存管理186
12.1頁186
12.2區187
12.3獲得頁189
12.3.1獲得填充為0的頁190
12.3.2釋放頁191
12.4kmalloc()191
12.4.1gfp_mask標志192
12.4.2kfree()195
12.5vmalloc()196
12.6slab層197
12.6.1slab層的設計198
12.6.2slab分配器的介面200
12.7在棧上的靜態分配203
12.7.1單頁內核棧203
12.7.2在棧上光明正大地工作203
12.8高端內存的映射204
12.8.1永久映射204
12.8.2臨時映射204
12.9每個CPU的分配20512.10新的每個CPU介面206
12.10.1編譯時的每個CPU數據206
12.10.2運行時的每個CPU數據207
12.11使用每個CPU數據的原因208
12.12分配函數的選擇209
12.13小結209
第13章虛擬文件系統210
13.1通用文件系統介面210
13.2文件系統抽象層211
13.3Unix文件系統212
13.4VFS 對象及其數據結構213
13.5超級塊對象214
13.6超級塊操作215
13.7索引節點對象217
13.8索引節點操作219
13.9目錄項對象222
13.9.1目錄項狀態222
13.9.2目錄項緩存223
13.10目錄項操作224
13.11文件對象225
13.12文件操作226
13.13和文件系統相關的數據結構230
13.14和進程相關的數據結構232
13.15小結233
第14章塊I/O層234
14.1剖析一個塊設備234
14.2緩沖區和緩沖區頭235
14.3bio結構體237
14.3.1I/O向量238
14.3.2新老方法對比239
14.4請求隊列240
14.5I/O調度程序240
14.5.1I/O調度程序的工作241
14.5.2Linus 電梯241
14.5.3最終期限I/O調度程序242
14.5.4預測I/O調度程序244
14.5.5完全公正的排隊I/O調度程序244
14.5.6空操作的I/O調度程序245
14.5.7I/O調度程序的選擇245
14.6小結246
第15章進程地址空間247
15.1地址空間247
15.2內存描述符248
15.2.1分配內存描述符249
15.2.2撤銷內存描述符250
15.2.3mm_struct 與內核線程250
15.3虛擬內存區域251
15.3.1VMA標志251
15.3.2VMA 操作253
15.3.3內存區域的樹型結構和內存區域的鏈表結構254
15.3.4實際使用中的內存區域254
15.4操作內存區域255
15.4.1find_vma()256
15.4.2find_vma_prev()257
15.4.3find_vma_intersection()257
15.5mmap()和do_mmap():創建地址區間258
15.6mummap()和do_mummap():刪除地址區間259
15.7頁表260
15.8小結261
第16章頁高速緩存和頁回寫262
16.1緩存手段262
16.1.1寫緩存262
16.1.2緩存回收263
16.2Linux 頁高速緩存264
16.2.1address_space對象264
16.2.2address_space 操作266
16.2.3基樹267
16.2.4以前的頁散列表268
16.3緩沖區高速緩存268
16.4flusher線程268
16.4.1膝上型計算機模式270
16.4.2歷史上的bdflush、kupdated 和pdflush270
16.4.3避免擁塞的方法:使用多線程271
16.5小結271
第17章設備與模塊273
17.1設備類型273
17.2模塊274
17.2.1Hello,World274
17.2.2構建模塊275
17.2.3安裝模塊277
17.2.4產生模塊依賴性277
17.2.5載入模塊278
17.2.6管理配置選項279
17.2.7模塊參數280
17.2.8導出符號表282
17.3設備模型283
17.3.1kobject283
17.3.2ktype284
17.3.3kset285
17.3.4kobject、ktype和kset的相互關系285
17.3.5管理和操作kobject286
17.3.6引用計數287
17.4sysfs288
17.4.1sysfs中添加和刪除kobject 290
17.4.2向sysfs中添加文件291
17.4.3內核事件層293
17.5小結294
第18章調試295
18.1准備開始295
18.2內核中的bug296
18.3通過列印來調試296
18.3.1健壯性296
18.3.2日誌等級297
18.3.3記錄緩沖區298
18.3.4syslogd和klogd298
18.3.5從printf()到printk()的轉換298
18.4oops298
18.4.1ksymoops300
18.4.2kallsyms300
18.5內核調試配置選項301
18.6引發bug並列印信息301
18.7神奇的系統請求鍵302
18.8內核調試器的傳奇303
18.8.1gdb303
18.8.2kgdb304
18.9探測系統304
18.9.1用UID作為選擇條件304
18.9.2使用條件變數305
18.9.3使用統計量305
18.9.4重復頻率限制305
18.10用二分查找法找出引發罪惡的變更306
18.11使用Git進行二分搜索307
18.12當所有的努力都失敗時:社區308
18.13小結308
第19章可移植性309
19.1可移植操作系統309
19.2Linux移植史310
19.3字長和數據類型311
19.3.1不透明類型313
19.3.2指定數據類型314
19.3.3長度明確的類型314
19.3.4char型的符號問題315
19.4數據對齊315
19.4.1避免對齊引發的問題316
19.4.2非標准類型的對齊316
19.4.3結構體填補316
19.5位元組順序318
19.6時間319
19.7頁長度320
19.8處理器排序320
19.9SMP、內核搶占、高端內存321
19.10小結321
第20章補丁、開發和社區322
20.1社區322
20.2Linux編碼風格322
20.2.1縮進323
20.2.2switch 語句323
20.2.3空格324
20.2.4花括弧325
20.2.5每行代碼的長度326
20.2.6命名規范326
20.2.7函數326
20.2.8注釋326
20.2.9typedef327
20.2.10多用現成的東西328
20.2.11在源碼中減少使用ifdef328
20.2.12結構初始化328
20.2.13代碼的事後修正329
20.3管理系統329
20.4提交錯誤報告329
20.5補丁330
20.5.1創建補丁330
20.5.2用Git創建補丁331
20.5.3提交補丁331
20.6小結332
參考資料333
㈧ linux 多核使用什麼內核鎖
從最初的原子操作,到後來的信號量,從大內核鎖到今天的自旋鎖。這些同步機版制的發展伴隨權Linux從單處理器到對稱多處理器的過渡;
伴隨著從非搶占內核到搶占內核的過度。Linux的鎖機制越來越有效,也越來越復雜。
Linux的內核鎖主要是自旋鎖和信號量。
自旋鎖最多隻能被一個可執行線程持有,如果一個執行線程試圖請求一個已被爭用(已經被持有)的自旋鎖,那麼這個線程就會一直進行忙循環——旋轉——等待鎖重新可用。要是鎖未被爭用,請求它的執行線程便能立刻得到它並且繼續進行。自旋鎖可以在任何時刻防止多於一個的執行線程同時進入臨界區。
Linux中的信號量是一種睡眠鎖。如果有一個任務試圖獲得一個已被持有的信號量時,信號量會將其推入等待隊列,然後讓其睡眠。這時處理器獲得自由去執行其它代碼。當持有信號量的進程將信號量釋放後,在等待隊列中的一個任務將被喚醒,從而便可以獲得這個信號量。
㈨ linux內核:非同步中斷,搶占及SMP都是什麼意思
非同步中斷就是中斷的中斷源不是當前進程,其實硬體中斷都是非同步的。
搶占是指高優先順序的進程可以強占低優先順序的進程的運行資源。
SMP,是對稱多處理的意思,就是幾個CPU核心對於內存來講是地位相同的,沒有主次之分