進程優先級的基本概念
在linux系統中,進程優先級(priority)決定了進程執行的順序。優先級較高的進程優先獲得cpu資源,從而提高了執行的優先權。優先級值越低,進程的優先級越高,這意味著該進程更有可能被cpu優先執行。合理配置進程的優先級對于提升系統的整體性能至關重要。
此外,Linux還提供了將進程運行到指定CPU的功能。通過將不重要的進程分配到特定的CPU上,可以更有效地利用CPU資源,避免系統性能下降。
如何查看系統進程
在Linux或unix系統中,我們可以使用ps -l命令來查看當前運行的進程。輸出信息中包含了多個有用的字段,幫助我們理解每個進程的狀態。以下是一些重要字段:
- UID:表示進程的執行者身份。
- PID:代表進程的標識符。
- PPID:表示該進程的父進程ID。
- PRI:進程的優先級。值越小,優先級越高。
- NI:進程的nice值,影響進程的優先級。
PRI和NI:優先級與Nice值
PRI(Priority)是進程的優先級,其值越小,優先級越高,進程越有可能先執行。NI(Nice)是進程的優先級修正值,可以調整進程的優先級。通過修改nice值,用戶可以間接地影響進程的PRI值。
具體地,進程的新PRI值計算公式為:
PRI(new) = PRI(old) + nice
當nice值為負時,進程的優先級會變小(優先級提升);當nice值為正時,進程的優先級會變大(優先級降低)。nice值的范圍是-20到19(PRI的值為0~99),越小表示優先級越高,越大表示優先級越低。
查看和調整進程優先級
在Linux中,查看進程優先級的常用命令是top。通過top命令,我們不僅能夠查看各個進程的優先級,還能實時調整進程的nice值:
- 輸入top命令啟動進程監視。
- 按r鍵,選擇需要調整的進程PID。
- 輸入新的nice值來調整該進程的優先級。
除了top命令外,Linux還提供了nice和renice命令來分別調整進程的初始優先級和修改已經運行中的進程的優先級。
補充概念-競爭、獨立、并行、并發
- 競爭性:系統進程數量眾多,而CPU資源只有少量,甚至1個,所以進程之間是具有競爭屬性的。為了高效完成任務,更合理競爭相關資源,便具有了優先級。
- 獨立性:多進程運行,需要獨享各種資源,多進程運行期間互不干擾。
- 并行:多個進程在多個CPU下分別,同時進行運行,這稱之為并行。
- 并發:多個進程在一個CPU下采用進程切換的方式,在一段時間之內,讓多個進程都得以推進,稱之為并發。
進程切換
CPU上下文切換:其實際含義是任務切換,或者CPU寄存器切換。當多任務內核決定運行另外的任務時,它保存正在運行任務的當前狀態,也就是CPU寄存器中的全部內容。這些內容被保存在任務自己的堆棧中,入棧工作完成后就把下一個將要運行的任務的當前狀況從該任務的棧中重新裝入CPU寄存器,并開始下一個任務的運行,這一過程就是context switch。
時間片:當代計算機都是分時操作系統,每個進程都有它合適的時間片(其實就是一個計數器)。時間片到達,進程就被操作系統從CPU中剝離下來。
Linux2.6內核進程O(1)調度隊列
上圖是Linux2.6內核中進程隊列的數據結構,之間關系也已經給大家畫出來,方便大家理解。
- 一個CPU擁有一個runqueue,如果有多個CPU就要考慮進程個數的負載均衡問題。
- 優先級:
- 普通優先級:100?139(我們都是普通的優先級,想想nice值的取值范圍,可與之對應!)
- 實時優先級:0?99(不關心)
活動隊列及其優化
在操作系統的進程調度中,活動隊列(Active Queue)用于管理處于運行狀態的進程。活動隊列不僅管理進程的排隊順序,還涉及進程的優先級和調度策略。以下是活動隊列的關鍵概念及其優化過程的整理:
活動隊列的基本概念
- nr_active:表示當前活動隊列中處于運行狀態的進程總數。它用于記錄系統中所有正在運行的進程數量。
- queue[140]:這是一個數組,其中每個元素對應一個優先級隊列。進程按照優先級排隊,相同優先級的進程使用先進先出(FIFO)規則進行調度。數組下標代表進程的優先級,因此queue[0]表示優先級最高的進程隊列,queue[139]表示優先級最低的進程隊列。
進程調度的基本過程
操作系統根據活動隊列進行進程調度的過程如下:
- 遍歷隊列:從queue[0]開始遍歷,查找非空的進程隊列。
- 選擇最高優先級的進程隊列:找到第一個非空隊列,該隊列中的進程具有最高的優先級。
- 選中并執行進程:從該非空隊列中選擇第一個進程進行調度執行。
- 調度完成:該進程開始執行,調度過程結束。
該過程的時間復雜度通常為常數時間,因為隊列的遍歷通常是有限的,但存在低效的情況。
低效問題及優化方案
直接遍歷queue[140]來查找非空隊列存在效率問題,尤其在系統中進程數量較多時,這種遍歷方式會變得低效。為了提高查找非空隊列的效率,可以通過使用位圖(bitmap)進行優化:
- bitmap[5]:為了提高查找非空隊列的效率,可以使用位圖來標識每個進程隊列是否為空。此位圖有140個位置,表示140個進程隊列,每個位置使用5個字節(5 * 32位),每一位表示相應隊列的空閑狀態。
- 優化效果:通過位圖的使用,可以在常數時間內快速定位到第一個非空隊列,從而大大提高查找和調度的效率。
過期隊列
過期隊列和活動隊列結構一模一樣。過期隊列上放置的進程,都是時間片耗盡的進程。當活動隊列上的進程都被處理完畢之后,對過期隊列的進程進行時間片重新計算。
過期隊列與活動隊列的結構
過期隊列和活動隊列在結構上非常相似,都是由一個隊列組成,用于管理不同優先級的進程。其基本結構如下:
- 過期隊列:這是放置已經超時或者不再需要立即執行的進程隊列。系統會根據進程的優先級來調度這些進程,通常只有在特定的條件下,才會將這些進程重新激活。
- 活動隊列:這個隊列用于管理當前需要執行的進程。處于活動隊列中的進程會按照優先級順序執行,直至完成。
過期隊列和活動隊列的關鍵點:
當活動隊列中的進程被處理完畢后,系統會重新計算過期隊列中進程的時間片,并重新將其加入活動隊列,等待重新執行。
在操作系統中,active和expired指針用于指向活動隊列和過期隊列的內容。具體作用如下:
- active指針:該指針始終指向活動隊列,管理當前需要執行的進程。當隊列中有進程時,active指針指向活動隊列的第一個進程,系統從該進程開始調度。
- expired指針:與active指針類似,expired指針指向過期隊列。過期隊列存儲的是已超時的進程,等待重新激活并加入活動隊列進行調度。
盡管active和expired指針指向的是兩個不同的隊列,但它們之間的轉換并沒有特別復雜的關聯。當一個進程的執行時間片結束后,系統會將其從活動隊列移到過期隊列。當過期隊列中的進程恢復執行時,它們會再次被移動到活動隊列。