1.程序描述符及任務結構
linux核心把程序存放在叫做任務佇列的雙向迴圈鍊錶中。鍊錶中的每一項都是型別為task_struct,稱為程序描述符的結構。程序描述符包含乙個具體程序的所有資訊。
task_struct相對較大,在32位的機器長,它大約有1.7k位元組。程序描述符中的資料能完整的描述乙個正在執行的程式:它開啟的檔案、程序的位址空間、掛起的訊號、程序的狀態,還有其他更多資訊(參見下圖)。
核心在每個程序的核心棧底建立乙個struct thread_info結構,使它記錄下相應程序的task_struct的位置。如下圖所示:
結構體thread_info的定義如下:
2.程序狀態
程序描述符中的state域描述了程序當前的狀態,該域的值為下列五種之一:
1.task_running(執行):程序是可執行的;或者它正在執行,或者處於執行佇列中等待執行。
2.task_interruptible(可中斷):程序正在睡眠(阻塞),等待某些條件達成。
3.task_uninterruptible(不可中斷):除了不會因為接受到訊號而被喚醒從而投入執行外,這個狀態與可打斷狀態一樣(使用的較少)。
4.task_zombie(僵死):該程序已經結束了,但是其父程序還沒有呼叫wait4()系統呼叫。為了父程序能夠獲知它的訊息,子程序的程序描述符仍然被保留著。一旦父程序呼叫了wait4(),程序描述符就會立即被釋放。
5.task_stopped(停止):程序停止執行;程序沒有投入執行也不能投入執行。通常這種狀態發生在接受到sigstop、sigtstp等訊號的時候。
程序狀態之間的轉移圖如下所示:
3.程序家族樹
linux系統的程序之間存在乙個明顯的繼承關係,在linux系統中也是如此。所有的程序都是pid為1的init程序的後代。
系統中的每個程序必有乙個父程序。相應的,每個程序也可以擁有零個或多個子程序。程序間的關係包含在程序描述符中。每個task_struct都包含乙個指向其父程序的task_struct指標parent,還包含乙個稱為children的子程序鍊錶,由此即構成了linux系統中的程序家族樹。
4.程序建立
linux建立程序分為兩個步驟:(1)fork();(2)exec()。首先fork()通過拷貝當前程序建立乙個子程序。子程序與父程序的唯一區別僅僅在於pid、ppid(父程序id)和某些資源與統計量(例如掛起的訊號,它沒有必要被繼承)。exec()函式負責讀取可執行檔案並將其載入位址空間開始執行。
傳統的fork()系統呼叫直接把所有的資源複製給新建立的程序。這種實現過於簡單並且效率底下,因為它拷貝的資料也許並不共享。linux的fork()採用寫時拷貝(copy-on-write)頁實現。寫時拷貝是一種可以推遲甚至免除拷貝資料的技術。核心此時並不複製整個程序的位址空間,而是讓父子程序共享同乙個拷貝。只有共享的資料需要寫入時,資料才會被複製。也就是說,資源的複製只有在需要寫入的時候才進行,在此之前,只是以唯讀方式共享。採用這種方法fork()的實際開銷就是複製父程序的頁表以及給子程序建立唯一的程序描述符。
fork()的主要工作是由copy_process()完成的,copy_process()做的事情如下:
5.執行緒在linux中的實現
linux實現執行緒的機制非常獨特。從核心的角度來說,它並沒有執行緒這個概念。linux把所有的執行緒都當做程序來實現。核心並沒有準備特別的排程演算法或是定義特別的資料結構來表徵執行緒。相反,執行緒僅僅被視作乙個與其他程序共享某些資源的程序。每個執行緒都擁有唯一隸屬於自己的task_struct,所以在核心中,它看起來就像是乙個普通程序。
5.程序終結
程序終結大部分的工作都是由do_exit()函式來完成,它做的事情如下:
至此,與程序相關聯的所有資源都被釋放掉了(假設程序是這些資源的唯一使用者)。程序不可執行並且處於task_zombie狀態。它所占用的所有資源就是核心棧、thread_info和task_struct結構。此時這些資源還沒有被釋放的唯一目的就是向它的父程序提供資訊。父程序檢索到資訊後,有程序所持有的剩餘記憶體被釋放,歸還給系統使用。
Linux核心設計與實現讀書筆記 1
我現在要做的科研專案涉及到核心程式設計的知識,所以在學校的圖書館借了一本 linux核心設計與實現 英文名 linux kernel development 打算通過這本書來了解一下linux核心各部分的原理。我選擇這本書的原因很簡單 薄。全書只有二百多頁,但內容還是很全面的。翻譯質量還可以,譯者還...
linux核心設計與實現讀書筆記 記憶體管理
一 頁 記憶體管理的基本單位 頁。核心中用struct page表示物理頁,位於,屬性包括flag頁狀態 count頁的引用計數,virtual頁虛擬位址。目的在於描述物理記憶體本身而非其中的資料。1 獲得頁 核心 alloc pages gft t gft mask,order 連續分配2n個連續...
《Linux核心設計與實現》讀書筆記 程序排程
程序排程程式負責決定將哪個程序投入執行,何時執行以及執行多長時間。在執行態程序之間分配有限的處理器時間資源。多工系統分為搶占式和非搶占式。linux使用搶占式。大部分現代系統都是搶占式 io消耗型 處理器消耗型程序 把大多時間用於執行 的程序。程序優先順序 nice值 20 19,值越大優先順序越低...