Linux 內核子系統之內存與進程管理子系統

Linux 內核子系統的組成

 

由以上7個子系統組成。

一、內存管理子系統

職能:

1、從虛擬地址到物理地址映射的管理。

2、物理內存分配的管理。

地址映射管理

 

2.1虛擬地址空間分佈

Linux中使用的是虛擬地址,但是在訪問硬件的時候使用的是物理地址。比如程序中用malloc函數分配的都是虛擬地址,但是硬件在使用時用的是物理地址,這其中就有一個轉化關係。

它所支持的虛擬地址空間是由硬件地址總線寬度決定的,比如32位地址總線支持4GB虛擬內存。

用戶空間(0-3G):用戶程序。

內核空間(3-4G):直接映射區3G-3G+896MB.

Vmalloc區,

永久內核映射,

固定映射的線性地址。

2.2虛擬地址轉化爲物理地址

CR3存放了頁目錄的基地址。

10位和CR3寄存器相加,就可以找到頁目錄裏的頁目錄項。

頁目錄項裏存放的是頁表的基地址。

頁表的基地址再加上中間10位的值就可以找到物理頁。

物理頁再加上最後12位的偏移就可以找到物理頁(通常4k)的存儲單元了。

 

直接映射區裏:虛擬地址=3G+物理地址

Vmalloc區:可以映射到高端和低端內存

永久映射區:高端內存

固定映射的線性地址:固定訪問一些寄存器

 

物理內存的分配

 

程序通過malloc等函數先申請到虛擬地址,當需要用到物理地址時通過請頁異常獲得物理地址。通過Kmalloc得到的虛擬地址時,虛擬地址和物理地址已經綁定了。

 

二、進程管理子系統

程序:存放在磁盤上的一系列代碼和數據的可執行映像,是一個靜止的實體

進程:是一個執行中的程序,他是動態的實體。

 

進程四要素

1.有一段程序供其執行。這段程序不一定是某個進程所專有,可以與其他進程共用。

2.有進程專用的內核空間堆棧。

3.在內核中有一個task_struct數據結構,即通常所說的“進程控制塊”。有了這個數據結構,進程才能成爲內核調度的一個基本單位接受內核的調度。

4.有獨立的用戶空間

 

Linux進程狀態

 

1.TASK_RUNNING

進程正在被CPU執行,或者已經準備就緒,隨時可以執行。當一個進程剛被創建時,就處於TASK_RUNNING狀態。

2.TASK_INTERRUPTINLE

處於等待中的進程,等待條件爲真時被喚醒,也可以被信號或者中斷喚醒。

3.TASK_UNINTERRUPTINLE

處於等待中的進程,待資源有效時喚醒,但不可以由其它進程通過(signal)或中斷喚醒。

4.TASK_KILLABLE

Linux2.6.25新引入的進程睡眠狀態,原理類似於TASK_UNINTERRUPTIBLE,但是可以被致命信號(SIGKILL)喚醒。

5.TASK_TRACED

正處於被調試狀態的進程

6.TASK_DEAD

進程退出時(調用do_exit),所處的狀態。

 

Linux進程的描述

linux內核代碼中,線程、進程都使用結構task_struct(sched.h)來表示,它包含了大量描述進程/線程的信息,其中比較重要的有:

Pid_t pid; //進程號

Long state;//進程狀態

Int prio;//進程優先級

 

Linux進程調度

學習調度需要掌握哪些知識點

1、調度策略

實時進程的優先級比普通進程高。

SCHED_NORMAL(SCHED_OTHER):普通的分時進程

SCHED_FIFO:先入先出的實時進程

SCHED_RR:時間輪轉的實時進程

SCHED_BATCH:批處理進程

SCHED_IDLE:只在系統空閒時才能被調度執行的進程

2、調度時機

 即schedule()函數什麼時候被調用?

主動式:

在內核中直接調用schedule()。當進程需要等待資源等而暫時停止運行時,會把自己的狀態置於掛起(睡眠),並主動請求調度,讓出CPU

範例:

1、current->state = TASK_INTERRUPTIBLE;

2、Schedule();

Current是一個指針,指向當前正在運行的進程的task_struct

被動式:搶佔式

分爲:用戶態搶佔(linux2.4linux2.6)和內核態搶佔(linux2.6)

用戶搶佔發生在:

從系統調用返回用戶空間。

從中斷處理程序返回用戶空間。

內核即將返回用戶空間的時候,如果need_resched標誌被設置,會導致schedule()被調用,即發生用戶搶佔。

當某個進程耗盡他的時間片時,會設置need_resched標誌

當一個優先級更高的進程進入可執行狀態的時候,也會設置need_resched標誌。

用戶態搶佔缺陷

進程/線程一旦運行到內核態,就可以一直執行,直到它主動放棄或時間片耗盡爲止。這樣會導致一些非常緊急的進程或線程將長時間得不到運行,降低整個系統的實時性。

改進方式

允許系統在內核態也支持搶佔,更高優先級的進程/線程可以搶佔正在內核態運行的低優先級進程/線程。

內核搶佔可能發生在:

中斷處理程序完成,返回內核空間之前。

當內核代碼再一次具有可搶佔性的時候,如解鎖使能軟中斷等。

在支持內核搶佔的系統中,某些特例下是不允許搶佔的;

1內核正在運行中斷處理

2內核正在進行中斷上下文的Bottom Half (中斷的底半部)處理。

硬件中斷返回前會執行軟中斷,此時仍然處於中斷上下文中

3進程正持有spinlock自旋鎖、writelock/readlock讀寫鎖等

當持有這些鎖時,不應該被搶佔,否則由於搶佔將可能導致其他進程長期得不到鎖,而讓系統處於死鎖狀態。

4內核正在執行調度程序scheduler。搶佔的原因就是爲了進行新的調度,沒有理由將調度程序搶佔掉再運行調度程序。

爲保證linux內核在以上情況下不會被搶佔,搶佔式內核使用了一個變量preempt_count,稱爲內核搶佔計數。這一變量被設置在進程的thread_info結構中。每當內核要進入以上幾種狀態時,變量preempt_count就加1,指示內核不允許搶佔。每當內核從以上幾種狀態退出時,變量preempt_count就減1,同時進行可搶佔的判斷與調度。

3、調度步驟

Schedule函數工作流程如下

1)清理當前運行中的進程;

2)選擇下一個要運行的進程;

3)設置新進程的運行環境。

4)進程上下文切換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章