系統核心解析:深入操作系統內部機制——進程管理與控制指南(三)【進程優先級/切換/調度】


???~~~~~~歡迎光臨知星小度博客空間~~~~~~???

???零星地變得優秀~也能拼湊出星河~???

???我們一起努力成為更好的自己~???

???如果這一篇博客對你有幫助~別忘了點贊分享哦~???

???如果有什么問題可以評論區留言或者私信我哦~???

??????個人主頁??????

????????前面我們已經學習了進程的前置知識,今天這一篇博客我們繼續來學習進程,準備好了嗎~我們發車去探索進程的奧秘啦~🚗🚗🚗🚗🚗🚗

目錄

進程優先級😜

基本概念😘

Linux 中的進程優先級😍

PRI 和 NI😜

優先級計算公式😄

查看進程優先級😀

調整進程優先級的方法😋

使用 nice 和 renice 命令🙃

使用 top 命令動態調整😁

使用系統調用 setpriority 和 getpriority👍

總結與對比🐷

進程的競爭性、獨立性、并行與并發😊

進程切換(Context Switching)😀

什么是進程切換?😊

為什么會進程切換??

進程切換步驟😭

Linux O(1) 調度器😍

理論核心架構😜

調度過程 😜

隊列交換 🙃

為什么叫O(1)算法?👌

總結🐷


進程優先級😜

基本概念😘

1. 什么是進程優先級?

? ? 進程優先級(Priority)操作系統調度器用來決定哪個進程先獲得 CPU 資源的一種機制優先級高的進程會優先被調度執行。注意優先級與“權限”不同優先級決定的是“誰先誰后”,而權限決定的是“能否訪問”。

2. 為什么需要進程優先級?

? ? 資源有限性:CPU 資源有限,而進程數量眾多,需要通過優先級合理分配資源。

? ? 系統性能優化:通過調整進程優先級,可以確保關鍵任務優先執行,提升系統整體性能。

Linux 中的進程優先級😍

PRI 和 NI😜

? ? PRI(Priority):進程的實際優先級,值越小優先級越高

? ? NI(Nice):用于調整 PRI 的修正值,用戶可通過修改 NI 來間接影響 PRI。

優先級計算公式😄

PRInew?=PRIold?+nice

? ? ????????nice 的取值范圍為 -20 到 19,共 40 個級別【Linux 是一個分時操作系統,這一個范圍也保證了一定的公平公正】,過度調高某個進程的優先級可能導致其他進程“饑餓”【其他進程無法得到調度和CPU資源】

? ? ????????PRI 的范圍一般為 60 到 99(Linux 默認范圍),Nice 值的 40 個級別(-20 到 19)正好一對一地映射到優先級(PRI)的 40 個級別(60 到 99)上。 NI 是用戶可見的、可調整的“輸入”,而 PRI 是內核內部實際使用的“輸出”值。

查看進程優先級😀

使用 ps -l ps -al 命令

? ? 我們可以發現【ps -l】和【ps -al】查詢到的進程是兩種不同的結果~這也就是它們的區別所在,我們來看看下面的對比表格~

特性ps -lps -al
顯示范圍僅當前終端所有終端
用戶范圍僅當前用戶所有用戶
進程數量較少較多
終端顯示僅當前終端 (pts/0)多個終端 (pts/0, pts/1)

? ? ? ? 除此之外,我們還可以發現進程的 PRI?都為 80,NI?都為 0——這正是 Linux 進程調度默認行為的體現~

????????在大多數 Linux 系統中,80 是用戶進程啟動時的默認基準優先級。這個值(具體數值可能因內核版本和發行版略有不同,但 80 非常常見)被設計為調度隊列中的一個中間值。這意味著新創建的進程不會天然地擁有很高或很低的優先級,它們在競爭 CPU 時間時處于一個相對公平的起跑線上。

????????0 是默認的 Nice 值。Nice 值是用戶或系統用來對默認優先級進行微調的修正值。一個為 0 的 NI 值表示“不做任何調整”,所以進程的最終優先級 PRI 就等于默認的基準優先級 80 + 0 = 80

調整進程優先級的方法😋

使用 nicerenice 命令🙃

?????????nice 用于啟動一個進程并指定其 nice 值renice 用于修改已運行進程的 nice 值~

非特權用戶只能調低優先級(提高 nice 值),不能調高(降低 nice 值)~

# 啟動一個進程(code)并設置 nice 值為 10
nice -n 10 ./code# 修改已運行進程(PID=4340)的 nice 值為 5
renice -n 15 -p 4340

注意事項:普通用戶只能降低優先級(增加 NI 值),只有 root 用戶才能提高優先級(設置負的 NI 值)。nice 用于啟動新進程時設置,renice 用于修改已運行進程的優先級。

使用 top 命令動態調整😁

  1. 命令行輸入top;

  2. r

  3. 輸入進程 PID;

  4. 輸入新的 nice 值。

  5. 按q退出

注意事項:這是交互式實時調整,同樣受權限限制(普通用戶不能設置負值)【與 renice 命令完全相同。在 top 界面中,如果你是普通用戶,嘗試輸入負值會得到 “Operation not permitted” 的錯誤】修改僅對進程的當前運行實例有效,進程重啟后恢復默認優先級。

使用系統調用 setprioritygetpriority👍

注意事項:需要在程序代碼中調用,主要權限限制與命令行相同。必須包含完善的錯誤處理(如檢查返回值),適合在應用程序中實現自適應的優先級管理。

總結與對比🐷

特性nice / renice 命令top 命令系統調用
使用場景命令行、腳本交互式實時監控與調整程序內部集成
控制對象新進程 / 已存在進程已存在進程自身或其他進程(編程控制)
靈活性交互式,中最高,可編程邏輯控制
權限要求普通用戶只能降級普通用戶只能降級普通用戶只能降級
持久性進程運行期間有效進程運行期間有效進程運行期間有效
主要優勢簡單直接,易于腳本化實時直觀,結合系統監控靈活自動化,嵌入程序邏輯

通用重要注意事項

  1. 權限是核心:記住 -20-1?【負值】的區間是 root 的“特權區”。

  2. 公平性:不要濫用高優先級,否則可能導致系統資源饑餓(Starvation),影響其他重要進程和系統整體穩定性。

  3. 非永久性:所有修改都只在進程生命周期內有效,進程重啟后設置失效。

進程的競爭性、獨立性、并行與并發😊

競爭性多個進程競爭有限的 CPU 資源,優先級用于解決競爭問題

獨立性進程之間相互隔離,一個進程的崩潰不會直接影響其他進程

并行多個進程多個 CPU 核心上同時執行

并發多個進程一個 CPU 核心上通過時間片輪轉交替執行,宏觀上間隔時間很短看似同時運行

進程切換(Context Switching)😀

什么是進程切換?😊

????????進程切換是指操作系統將當前正在運行的進程掛起,并恢復另一個進程執行的過程。這個過程也叫做 CPU 上下文切換(CPU Context Switching)

? ????????? 那么什么是上下文呢?前面對于進程學習,我們簡單介紹了一下上下文數據~? ?接下來我們來看看什么是CPU上下文?

  • 理論:CPU上下文指的是在任務(進程/線程)執行時,CPU寄存器程序計數器在任意時刻的狀態。CPU內的寄存器只有一份,但是上下文可以有多份,分別對應不同的進程寄存器存儲著進程的臨時數據、地址、狀態信息程序計數器(PC)存儲著下一條要執行的指令地址

  • 比喻:這就像 一個廚師的工作臺當前狀態——哪些食材正在處理、刀放在哪、火開到多大、菜譜翻到了哪一頁。這一切定義了“工作做到哪一步了”。

為什么會進程切換??

  • 理論:操作系統為了實現并發(Concurrency)讓多個進程在一段時間內“看起來”同時運行。當一個進程的時間片用完、或需要等待I/O操作、或有更高優先級進程就緒時,就需要切換。

  • 比喻:餐廳經理(操作系統)為了保證公平性和效率,規定每個廚師一次只能在廚房工作一段時間(時間片)。時間到了就必須換人,讓其他廚師也能用廚房,防止一個廚師霸占廚房。

進程切換步驟😭

  1. 保存上下文 (Save the Context):

    • 理論:將當前進程的CPU寄存器狀態全部保存到它的內核棧(Kernel Stack) 中。

    • 比喻:廚師A被叫出廚房前,他必須迅速而準確地在自己的記事本(內核棧) 上記下所有工作狀態:“洋蔥切了一半,還剩3個,湯用中火燉了5分鐘,鹽放了2勺...”。

  2. 選擇下一個進程 (Pick Next Process):

    • 理論:由操作系統的調度器(Scheduler) 從就緒隊列中選擇一個最合適的進程來運行。

    • 比喻:餐廳經理查看任務板(運行隊列),根據優先級規則,決定接下來讓哪位廚師(進程)進入廚房。

  3. 恢復上下文 (Restore the Context):

    • 理論:將下一個要運行進程的上下文信息,從其內核棧中加載到CPU的各個寄存器中。

    • 比喻:廚師B進入廚房。他并不關心上一位廚師做了什么。他拿出自己的記事本,按照上面的記錄恢復工作現場:“哦,我上次魚煎到一半,油溫是七成熱,下一步該翻面了...”。

  4. 跳轉執行 (Jump and Execute):

    • 理論:將程序計數器(PC)設置為新進程的下一條指令地址,CPU開始執行新進程的代碼。

    • 比喻:廚師B看了一眼記事本上記錄的下一步驟,然后開始繼續操作。

Linux O(1) 調度器😍

理論核心架構😜

運行隊列 (Runqueue):

  • 理論:Linux為每個CPU核心都維護一個struct runqueue(運行隊列)結構。這是調度的核心數據結構。

  • 比喻:這家餐廳的每個廚房(CPU核心) 都有自己獨立的任務管理區(運行隊列),這樣多個廚房可以同時工作,互不干擾,避免了廚師們擠在一個任務板前爭吵(避免了鎖競爭)。

優先級數組 (Priority Arrays) - 活動隊列與過期隊列:

  • 理論:每個運行隊列包含兩個prio_array_t結構的數組:活動隊列(active)過期隊列(expired)

    • 活動隊列 (active):存放所有時間片尚未耗盡的就緒進程。

    • 過期隊列 (expired):存放所有時間片已經耗盡的就緒進程【新增進程/時間片到了的進程

  • 比喻:每個廚房的任務管理區都有兩塊巨大的白板

    • “正在叫號”板 (Active Board):上面掛著所有還有工作時間的廚師的訂單。

    • “等待換班”板 (Expired Board):上面掛著所有工作時間已用完的廚師的訂單。

隊列結構 (Queue Structure):

  • 理論:每個prio_array_t包含:

    • queue[140]: 一個包含140個鏈表的數組。每個鏈表(queue[i])都是一個FIFO隊列,存放著所有優先級為i的進程。下標即優先級,目前我們主要了解O(1)調度算法如何管理調度下標為【100-139】的普通進程【0-99】的實時進程的管理調度后面再繼續了解~

    • bitmap[5]: 一個5*32=160位的位圖(bitmap),每一位代表一個優先級隊列是否為空(1為非空,0為空)。用于快速查找最高優先級的非空隊列。

  • 比喻

    • “正在叫號”白板上有140個掛鉤(queue[140],編號從0到139。編號越小,代表優先級越高(VIP掛鉤)。

    • 每個掛鉤上可以掛一串訂單(進程鏈表),同一掛鉤上的訂單優先級相同,按先來后到的順序排隊。

    • 經理手邊還有一個電子指示屏(bitmap,上面有140個小燈,每個燈對應一個掛鉤。如果某個掛鉤上有訂單,對應的燈就會亮起。經理一眼掃過屏幕,就能立刻知道哪個編號最小的亮燈掛鉤(即最高優先級的非空隊列)。

更加形象可以看看下面這張圖片:

調度過程 😜

  • 理論步驟

    1. 調度器查看active->bitmap,找到第一個被設置的位(即優先級最高的非空隊列)。

    2. active->queue[i]中取出第一個進程。

    3. 將該進程投入運行。

    4. 當該進程的時間片用完,它會被從CPU上剝離。

    5. 調度器重新計算它的時間片和新優先級(可能根據其行為交互式還是計算型進行動態調整),然后將其放入expired->queue[k]中(k是計算出的新優先級)。

    6. 重復步驟1-5,直到active隊列為空。

  • 比喻步驟

    1. 經理查看電子指示屏,找到編號最小的、燈還亮著的掛鉤(比如101號)。

    2. 他走到101號掛鉤前,取下最前面的那個訂單,叫對應的廚師(比如廚師A)進廚房工作。

    3. 廚師A在廚房工作,直到經理喊“時間到!”。

    4. 廚師A出來,經理根據他剛才的表現(是一直在切菜(CPU密集型)還是經常等送食材(I/O密集型)),重新評估他的效率,并給他分配新的下次工作時間(重置時間片)。

    5. 然后經理把廚師A的訂單掛到 “等待換班”板 的對應優先級的掛鉤上(比如新優先級變成了105)。

    6. 經理繼續從“正在叫號”板叫下一個廚師。

隊列交換 🙃

  • 理論:當active隊列完全為空時,調度器只需執行一個簡單的指針交換操作swap(active, expired)。之后,原來的過期隊列變成新的活動隊列,而空的活動隊列則成為新的過期隊列

  • 比喻:當 “正在叫號”板 上的所有訂單都被處理完,變得空空如也時。經理并不慌張,他做了一件非常聰明的事:直接把“正在叫號”和“等待換班”兩塊白板的標簽互換!瞬間,滿是訂單的“等待換班”板變成了新的“正在叫號”板,而空的板子則成為了新的“等待換班”板。所有等待的廚師又都有了新的工作時間。

為什么叫O(1)算法?👌

  • 理論:無論系統中有多少進程,查找下一個要運行的進程的時間都是一個常數。因為它不遍歷所有進程,而是通過查詢固定大小的bitmap(常數時間)操作固定數量的隊列(140個)來完成。

  • 比喻:無論餐廳有多少等待的廚師,經理決定下一個叫誰的時間都是一樣的。他只需要看一眼固定大小的電子指示屏,而不是從頭到尾數一遍所有廚師。

總結🐷

了解了這么多,我們可以看到Linux調度器的設計之美:

  • 效率:通過bitmap和雙隊列結構,將調度算法復雜度降為O(1)。

  • 公平:通過時間片輪轉和優先級結合,保證所有進程都能得到執行,不會出現“饑餓”現象。

  • 智能:調度器會根據進程的過去行為(I/O密集還是CPU密集)動態調整其優先級,讓交互式程序(如桌面點擊)響應更快,體驗更好。


???本篇博客內容結束,期待與各位優秀程序員交流,有什么問題請私信???

???如果這一篇博客對你有幫助~別忘了點贊分享哦~???

??????個人主頁??????


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/99032.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/99032.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/99032.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

量子-resistant密碼學研究

當亞馬遜CloudFront在2025年9月宣布為所有TLS連接默認啟用后量子加密支持時,這一舉措標志著抗量子密碼學從學術研究正式邁入大規模實用部署階段。與此同時,密碼學家們發出警告:一臺擁有不到一百萬噪聲量子比特的計算機,可能在一周…

ARM 架構的存儲器模型

ARM 架構的存儲器模型 ARM 的存儲器模型是一個相對復雜但設計精密的體系,它定義了處理器如何與內存進行交互,包括內存訪問的順序、可見性以及緩存行為等。這對于理解多核編程、并發控制和底層系統性能至關重要。 ARM 架構,特別是 ARMv8 及以后…

機器學習-多層感知機MLP

線性方法->多層感知機(MLP) 一個全連接(線性、dense)層有參數W∈Rm?nW\in\R^{m*n}W∈Rm?n,b∈Rmb\in\R^mb∈Rm,其用于計算輸出yWxb∈RmyWxb\in\R^myWxb∈Rm 線性回歸:全連接層有1個輸出softmax 回歸&a…

PostgreSQL——并行查詢

這里寫目錄標題一、并行查詢相關自己置參數二、并行掃描2.1、并行順序掃描2.2、并行索引掃描2.3、并行index-only掃描2.4、并行bitmap heap掃描三、并行聚合四、多表關聯4.1、Nested loop多表關聯4.2、Merge join多表關聯4.3、Hash join多表關聯了解 Oracle 的朋友應該知道 Ora…

智能體賦能金融多模態報告自動化生成:技術原理與實現流程全解析

在金融領域,研報作為決策參考的核心載體,其生成過程往往涉及海量數據采集、多維度分析及專業內容整合,傳統人工制作模式不僅耗時耗力,還難以滿足實時性與標準化需求。隨著人工智能技術的發展,“智能體賦能的金融多模態…

uniapp和vue3項目中引入echarts 、lime-echart(微信小程序、H5等)

目錄標題1、獲取 lime-echart插件2、安裝 echarts3、相關代碼4、在線定制5、效果截圖1、獲取 lime-echart插件 https://gitee.com/liangei/lime-echart 將其中組件和靜態資源分別放入當前項目對應的文件夾中: 2、安裝 echarts npm install echarts --save具體查…

ZYNQ7020+AD9361裸機驅動驗證

1. 程序編譯驗證 a. 下載源代碼 首先需要從GitHub下載相應的源碼,打開git bash,然后在mingwin中使用以下命令下載源碼。 git clone --recursive https://github.com/MicroPhase/antsdr_standalone.git 注意:在下載源碼的時候,使…

Grafana配置連接時候證書與mongosqld啟動證書的關系

目錄 證書角色說明 1. BI Connector 端的證書 (--sslPEMKeyFile) 2. Grafana 端的證書 (TLS/SSL Client Certificate & Key) 它們之間的關系 配置建議 情況一:只需要服務器驗證(最常見) 情況二:需要雙向SSL認證&#x…

解決HTML/JS開發中的常見問題與實用資源

在前端開發過程中,即使是經驗豐富的開發者也會遇到各種小問題。本文將聚焦于兩個常見問題的解決方案,并推薦一些國內可訪問的優質源碼學習網站,幫助開發者提升效率。 一、字符編碼與亂碼問題解決 在HTML和JavaScript開發中,字符編…

SQLI-labs[Part 2]

本篇為SQLI-labs的Write-Up的第二部分包含Level 23- Level 27Level 23 過濾注釋符 字符注入拼接語句發現注釋符沒有生效 應該是被過濾了那只能通過拼接語句來除去后面的影響拼接?id1 or 11?id1%27%20or%20%271%27%271源碼中最后的導致語句閉合 Level 24 字符二次注入成功登錄…

宋紅康 JVM 筆記 Day17|垃圾回收器

一、今日視頻區間 P169-P203 二、一句話總結 GC分類與性能指標;不同的垃圾回收器概述;Serial回收器:串行回收;ParNew回收器:并行回收;Parallel回收器:吞吐量優先;CMS回收器&#xff…

[硬件電路-194]:NPN三極管、MOS-N, IGBT比較

NPN三極管、MOS-N(N溝道MOS管)和IGBT(絕緣柵雙極型晶體管)在電子電路設計中各有其獨特的應用場景和優勢,以下從工作原理、特性、應用領域三個維度進行比較:工作原理NPN三極管:結構:由…

【代碼隨想錄day 25】 力扣 46. 全排列

視頻講解:https://www.bilibili.com/video/BV19v4y1S79W/?vd_sourcea935eaede74a204ec74fd041b917810c 文檔講解:https://programmercarl.com/0046.%E5%85%A8%E6%8E%92%E5%88%97.html#%E6%80%9D%E8%B7%AF 力扣題目:https://leetcode.cn/prob…

指針(五)后半

1、 qsort 函數1.1、qsort 函數排列結構體在這里&#xff0c;我們創建結構體類型的數組&#xff0c;用于 qsort 函數的傳參。#include<stdio.h> #include<stdlib.h> #include<string.h>struct Stu//創建結構體變量 {char name[30];int age; };struct Stu arr…

TDengine 特殊選擇函數 MODE() 用戶手冊

MODE 函數用戶手冊 函數定義 MODE(expr)功能說明 MODE() 函數返回指定列中出現頻率最高的值&#xff08;眾數&#xff09;。如果有多個值具有相同的最高頻率&#xff0c;系統會返回其中一個值。該函數會忽略 NULL 值。 算法原理 MODE 函數的計算過程如下&#xff1a; 數據…

智能外骨骼技術應用場景及價格可接受區間分析

一、引言 智能外骨骼機器人融合機械、人工智能和傳感器技術,增強或恢復人體運動能力。2025年,該技術在醫療康復、工業生產、軍事應用和消費市場快速普及。本文分析其應用場景、市場需求、典型產品、價格可接受區間及相關來源,探討普及的關鍵因素。 二、主要應用場景及產品…

Vue模板中傳遞對象或數組時,避免直接使用字面量[]和{}

在 Vue 中&#xff0c;直接在模板中使用 [] 或 {} 作為 prop 值會導致子組件不必要的重新渲染&#xff0c;因為每次父組件渲染時都會創建新的引用。以下是解決方案和最佳實踐&#xff1a; 1. 避免在模板中直接使用字面量 <!-- 避免這樣寫 --> <ChildComponent :items&…

【C++】list容器的模擬實現

目錄 1. 節點(list_node) 的結構 2. 哨兵位頭節點 3. list容器的成員變量 4. 插入/刪除操作 4.1 插入操作&#xff08;insert&#xff09; 4.2 刪除操作&#xff08;erase&#xff09; 5. 迭代器的實現 6. 不同迭代器和const容器的限制 7. 重載operator-> 8. 迭代器…

三大運營商eSIM手機業務開通加速

截至2025年9月11日&#xff0c;中國三大運營商eSIM手機業務開通情況呈現明顯差異化&#xff1a;中國聯通已率先支持eSIM手機業務&#xff0c;但僅限于特定城市和設備&#xff1b;中國移動和中國電信則處于"技術準備就緒&#xff0c;等待政策批復"階段&#xff0c;預計…

基于SpringBoot的足球論壇系統+論文示例參考

1.項目介紹 系統角色&#xff1a;管理員、普通用戶功能模塊&#xff1a;用戶管理、足球賽事、球員信息、推薦話題、帖子信息、周邊商城、訂單信息、系統管理等技術選型&#xff1a;SpringBoot&#xff0c;Vue等 測試環境&#xff1a;idea2024&#xff0c;jdk1.8&#xff0c;mys…