Linux核心設計基礎(九)之程序管理和排程

2021-08-27 17:48:18 字數 1524 閱讀 6686

在linux中程序用結構體task_struct來管理乙個程序所需的所有資訊(所以一般較大,在32位機上,大約有1.7kb)。為了提高效率,linux使用了一些卓越的技術。

linux建立程序迅速,正是因為slab分配器預先分配和重複使用task_struct,這樣就避免了動態分配和釋放所帶來的資源消耗(畢竟乙個task_struct較大,而且核心中程序的建立和消除很頻繁)。

這樣做是為了讓那些像x86那樣暫存器較少的硬體體系結構只需通過棧指標就能計算出它的位置,而避免使用額外的暫存器專門記錄。由於linux使用slab動態給乙個程序分配task_struct,所以linux在棧底(向下增長的棧,如圖,高位址在上,且棧從高位址向低位址延伸)用乙個資料結構指向slab中為之分配的task_struct,而這個資料結構是結構體thread_info,它的乙個成員是指向task_struct的指標。

linux建立乙個程序要依次呼叫fork()和exec()。fork()建立子程序時,父程序和子程序共享同乙份資源(以唯讀的方式共享),而只有當需要寫入時,資料才會被複製,從而使各個程序擁有各自的拷貝,這種將拷貝推遲到實際發生寫入時的技術稱為寫時拷貝。但對於那些fork()後立即呼叫exec()的就不用複製了(與父程序共享乙份資源即可),因為這時不會發生寫入,而大多數情況下,程序建立後會馬上執行乙個可執行的檔案,所以這種寫時拷貝可以避免拷貝大量根本就不會被使用的資料。這也是linux能快速執行程序的原因。

多工給linux的效率提出了嚴峻的挑戰。既要有併發的效果,又要保證公平。當代多數現代作業系統是在時間片和搶占上下功夫,從全域性的角度讓每個程序獲得各自理想的時間片。但linux獨樹一幟,它並沒有採取時間片達到公平排程。

(1)o(1) 排程:不管輸入有多大,排程程式都可以在恆定時間內完成工作,這對於大伺服器的工作負載很理想。但在有很多互動程式要執行的桌面環境表現不佳。為此,2.6核心的開發人員引入了著名的」反轉樓梯最後期限排程演算法「,也就是後來的完全公平排程演算法cfs。

(2)cfs(完全公平排程):允許每個程序執行一段時間、迴圈輪轉、選擇執行最少的程序作為下乙個執行程序,而不再採用分配給每個程序時間片的做法,cfs在所有可執行程序總數基礎上計算出乙個程序應該執行多久,而不是依靠優先順序(nice值)來計算時間片,nice值在cfs中被作為程序獲得處理器執行比的權重——更低的nice值(優先順序越高)的程序獲得更高的處理器使用權重。簡而言之一句話,以權重來代替實際的時間片。而這個排程週期則由cfs來定,為了較好的互動性,可以設定越小的排程週期,但同時要承受更高的切換代價和更差的系統總吞吐能力。但當程序趨於無窮時,高昂的切換開銷肯定不可接受,為此cfs引入最小粒度1ms——即每個程序最少能獲得1ms的執行時間,確保切換開銷被限制在一定範圍內。但這樣就產生了不公平,因為會有一些程序在這個週期內得不到時間片,所以cfs並非是乙個完美的公平排程(實際上,我個人認為不存在絕對公平的排程),不過通常情況下系統只會有幾百個可執行程序,所以cfs還是相當公平的:)

Linux核心之程序管理

linux核心之程序管理 支援執行緒的計算機系統裡面,程序作為資源分配的基本單位而存在,執行緒作為排程的基本單位而存在.執行緒僅擁有必不可少的一些資源,如 一組暫存器,堆疊資訊等等和其他執行緒共享同乙個程序的所有資源.所以,在同乙個程序的執行緒切換時不需要大量的儲存和恢復工作,同時由於共享同乙個儲存...

Linux核心程序管理之程序ID

乙個程序實體對應乙個task struct結構體,關於這個結構體後續的文章會有介紹,這裡我們只需要知道通過該結構體我們可以獲得該程序使用的所有資源資訊。程序id顧名思義就是程序的id,乙個程序有四種型別的id,分別是 乙個程序可能包含多個執行緒,組成乙個執行緒組,執行緒組內所有的執行緒的tgid都等...

Linux核心設計基礎(七)之系統呼叫

我理解的系統呼叫就是核心提供的一組使用者程序與核心進行互動的介面。除異常和陷入外,系統呼叫是核心唯一的合法入口。像 proc也是通過系統呼叫進行訪問的。系統呼叫的意義 系統呼叫的基本原理 系統呼叫通常的入口是c庫中定義的函式,也可以是自定義的函式 通過syscall進行呼叫 每個系統呼叫被賦予乙個系...