進程狀態+進程優先級+進程上下文切換解讀

一、進程狀態

什么是進程狀態?

進程狀態指的是在操作系統中進程在生命周期中所處的不同階段。

進程狀態有哪些呢?
在這里插入圖片描述

我們可以看到上述圖片
進程狀態分為:創建狀態、就緒狀態、運行狀態、阻塞狀態和終止狀態

所有的操作系統在實現進程狀態變化的時候都要符合上面的理論。
進程在運行的時候是需要資源的,也就是說進程之間是有競爭的,它們競爭的資源分為兩類:外設資源和CPU資源(輸入輸出設備統稱為外設資源,運算器和控制器統稱為CPU資源)

大部分的操作系統內部都要給每個CPU設置一個調度隊列多個CPU就要多個調度隊列,操作系統對調度隊列進行的管理方式就是先描述在組織

綜上所述,我們就知道了在操作系統中就要有一個struct runqueue

struct runqueue
{//隊列屬性int num; //隊列個數struct task_stuct* head;
}

所以說CPU的調度隊列是怎么樣拿到該進程的呢?

struct task_struct
{//所有的屬性struct list_head tasks;
}
struct list_head
{struct list_head* next;struct list_head* prev;
}

看上述的代碼,在struct task_struct里面有一個struct list_head tasks的變量,struct list_head里面包含兩個指針分別是next和prev指針,它是通過struct list_head來實現雙鏈表的。所以綜上所述我們就可以知道,只要我們得到struct task_struct結構體中的struct list_head tasks變量的地址,我們就可以利用偏移量來得到task_struct的起始地址。

既然我們知道task_struct的起始地址 = struct list_head變量的地址 - 偏移量了,那偏移量該怎么得到呢?

假設在地址為0處有一個struct task_struct變量,去訪問該變量中的struct list_head變量并進行取地址:&((struct task_struct*)0->tasks)。我們要知道的是,對于每一個進程來書,struct task_struct結構體的大小是固定的,所以說struct list_head在struct task_struct中的偏移量也是固定的。那么struct task_struct* start = &stract list_head task - &((struct task_struct*)0->tasks).

所以說在linux中PCB實現雙鏈表的這種方式就再也和類型沒有關系了,struct task_struct既可以屬于鏈表,同時也可以屬于其他數據結構。

在linux中是沒有就緒狀態的,所以我們認為就緒狀態和運行狀態不分家。在有些系統中,認為PCB處在運行隊列中但是未分配CPU資源叫做就緒狀態,正在CPU中執行的進程叫做運行狀態。

每個進程都要競爭CPU資源,所以就得把進程鏈入到調度隊列中。我們把上述這個行為叫做進程在CPU的調度隊列當中進行排隊。進行排隊時,該進程的狀態就叫做(r)運行狀態

運行狀態:該進程的PCB必須處在CPU的調度隊列中,只要在調度隊列中,進程就叫做運行狀態,隨時等待CPU的調度執行

阻塞狀態:當進程無法繼續執行,需要等待某些非CPU資源就緒時,就會進入阻塞狀態(進程進入阻塞狀態,PCB會被移除運行隊列,進入等待隊列)

掛起狀態:當內存空間嚴重不足時,操作系統會將進程的代碼,數據,堆棧等內存資源移出內存,換出磁盤的交換區里,但進程的PCB仍然保留在內存中,這就叫掛起狀態

新建狀態:操作系統為進程分配必要的資源,并為進程分配唯一的標識符

下面的狀態在kernel源代碼里定義:

/*
*The task state array is a strange "bitmap" of
*reasons to sleep. Thus "running" is zero, and
*you can test for combinations of others with
*simple bit tests.
*/
static const char *const task_state_array[] = {
"R (running)", /*0 */
"S (sleeping)", /*1 */
"D (disk sleep)", /*2 */
"T (stopped)", /*4 */
"t (tracing stop)", /*8 */
"X (dead)", /*16 */
"Z (zombie)", /*32 */
};

R運行狀態(running): 并不意味著進程?定在運行中,它表明進程要么是在運行中要么在運行隊列?。
? S睡眠狀態(sleeping): 意味著進程在等待事件完成(這里的睡眠有時候也叫做可中斷睡眠(interruptible sleep))。
? D磁盤休眠狀態(Disk sleep)有時候也叫不可中斷睡眠狀態(uninterruptible sleep),在這個狀態的進程通常會等待IO的結束。
? T停止狀態(stopped): 可以通過發送 SIGSTOP 信號給進程來停止(T)進程。這個被暫停的進程可以通過發送 SIGCONT 信號讓進程繼續運行。
? X死亡狀態(dead):這個狀態只是?個返回狀態,你不會在任務列表?看到這個狀態。

看下面這個代碼,代碼運行時我們發現它的狀態怎么會是S(睡眠狀態)狀態呢?不應該是R(運行狀態)嗎?
在這里插入圖片描述
在這里插入圖片描述
接下來我們再改一下代碼在這里插入圖片描述
很奇怪的就是為什么將while中的printf屏蔽了就變成了R狀態呢?

在這里插入圖片描述
原因就是printf是向顯示器打印內容的,訪問的是外設資源,外設的速度很慢,很大概率是無法就緒的,所以就是S狀態。但是有少數的概率會顯示R狀態

其實S這個狀態是一種淺度睡眠的狀態,我們可以使用ctrl+c來殺掉淺度睡眠,而D這種狀態則是深度睡眠,其不對任何事件進行響應,連操作系統都不能殺掉,除非是說進程自己醒過來。

僵尸進程

模擬實現僵尸進程
在這里插入圖片描述
運行代碼得到的結果如下:

在這里插入圖片描述
在這里插入圖片描述
我們看上述代碼會發現子進程比父進程先退出,父進程就會先處于一個僵尸狀態代碼、數據釋放掉,但是會保留struct task_struct,PCB會自動記錄進程退出時的退出信息,方便父進程讀取退出碼。

假設父進程一直不處理,一直處于僵尸進程,PCB一直存在于內存中,這就會導致內存的泄露。

那如果我們是父進程先退出呢?子進程會怎么樣?

孤兒進程

模擬實現孤兒進程
在這里插入圖片描述
運行結果如下:
在這里插入圖片描述
在這里插入圖片描述
我們查看進程狀態發現一個很奇怪的東西,就是這個1號進程是什么呢?

子進程被操作系統一號領養了,一號是一個叫做init的進程

在linu中init進程是什么?

它是系統啟動后運行的第一個用戶態進程,通常具有進程 ID(PID)為 1。init 進程的主要作用是初始化系統環境、啟動其他關鍵服務和守護進程,并管理系統的運行級別。

為什么要領養子進程呢?

因為孤兒進程也會退出,但是父進程早早就沒了,所以會被系統領養,本質上是為了回收孤兒進程防止內存泄漏。

進程退出不應該會變成僵尸進程嗎?為什么沒有看到父進程的僵尸狀態呢?

子進程的父進程的父進程是bash(外殼程序),父進程一旦退出,就會被bash回收,所以看不到父進程的僵尸狀態,具體過程看下面兩張圖。

在這里插入圖片描述

在這里插入圖片描述

二、進程的優先級

什么是進程的優先級?

在操作系統中,進程的優先級是用于決定進程調度順序的一個重要參數。優先級越高,進程獲得 CPU 時間片的機會就越大。總而言之就是進程得到某種資源的先后順序

在這里插入圖片描述
我們使用ps -al命令查看進程的優先級

UID : 代表執行者的身份
PID : 代表這個進程的代號
PPID :代表這個進程是由哪個進程發展衍生而來的,亦即父進程的代號
PRI :代表這個進程可被執行的優先級,其值越小越早被執行
NI :代表這個進程的nice值

PRI越小代表該進程優先級越高,它就是一個整數,存在于task_struct中,而NI是一個修正數據:PRI(new) = PRI(old) + nice 在linux中nice的取值范圍是-20~19,一共40個級別。

使用top來改變PRI,步驟如下:

top指令后,-r進入pid,接著輸入pid
在這里插入圖片描述
在這里插入圖片描述

補充進程的性質:

競爭性: 系統進程數目眾多,而CPU資源只有少量,甚至1個,所以進程之間是具有競爭屬性的。為了高效完成任務,更合理競爭相關資源,便具有了優先級
獨立性: 多進程運行,需要獨享各種資源,多進程運行期間互不干擾
并行: 多個進程在多個CPU下分別,同時進行運行,這稱之為并行
并發: 多個進程在?個CPU下采用進程切換的方式,在?段時間之內,讓多個進程都得以推進,稱之為并發

三、進程切換

在這里插入圖片描述
CPU內有很多寄存器,這些寄存器就是一套儲存空間,寄存器只有一套,屬于CPU本身,但是寄存器內部的數據可以有很多。進程在被切換的時候,進程PCB會保存該進程的上下文數據,以便進程再被調度的時候可以恢復數據。

看上述圖片中紅色括號中的queue數組,這個是什么呢?

其實queue數組類型是一個struct list_head類型,簡單的理解就是認為它是一個struct task_struct*類型,它可以使用struct list_head中的節點指針對進程進行關聯,這個進程的大小是140,下標[0,99]我們不需要理會,[100,139]剛好是40個,然而我們進程范圍是[60,99]剛剛好也是40個,所以我們知道操作系統根據進程的優先級將進程掛接在對應的下標上。

在linux中對進程調度的時候,用到一個bitmap[5],利用位圖的方式對queue數組進行遍歷,這樣能提高效率。但是為什么是5呢?因為一個整型4個byte,32個bit,那么5個就是160個bit,剛剛好對應下標140.

對應的比特位的位置表示的是數組中第幾個隊列比特位的內容表示的是隊列是否為空。

我們再看向上面的圖片會發現有兩個指針分別是:struct prio_array*,struct prio_array* expired,這兩個指針分別是活躍隊列過期隊列
CPU調度的時候直接從
active指針找到對應的queue[140],新增進程或者時間片到的進程,從CPU上剝離下來,被剝離下來的進程只能重新入隊列,入過期隊列。

既然如此為什么要有nice值呢?

如果我們要改PRI值的時候,我們能直接改嗎?答案是不能的,因為我們直接改PRI值那么進程就會被立即遷移到對應的隊列上,而有了nice值的話就不會影響active隊列中進程的調度,在expired隊列中對應的進程的優先級做出調整。

等到CPU調度完所有進程,所有進程都會跑到過期隊列。一旦active沒有進程了,這時只需要交換active,expired指針內容就可以了。

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

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

相關文章

Android 原生與 Flutter 通信完整實現 (Kotlin 版)

1. 項目配置 pubspec.yaml 添加依賴 dependencies:flutter:sdk: flutterprovider: ^6.0.52. Flutter 端實現 狀態管理類 // settings_provider.dart import package:flutter/foundation.dart;class SettingsProvider with ChangeNotifier {String _themeColor blue;bool _dark…

數字圖像處理3

圖像線性濾波——目的就是濾去噪聲,但是邊緣會模糊,整體也模糊線性:鄰域平均法(4鄰域平均和8鄰域平均)用當前運算點所在鄰域的平均值來代替該點的平均值im_for_read"D:\AAAproject\PYproject\EXPERuse\zaosheng.j…

Linux發行版分類與Centos替代品

讓centos7氣的不輕,這玩意兒太老了,什么都不好配置。 目錄Linux 發行版的大致分類1. Red Hat 系列(RPM 系)2. Debian 系列(DEB 系)3. Arch 系列4. SUSE 系列CentOS 7 的替代品推薦AlmaLinux 和 Rocky Linux…

大語言模型提示工程與應用:大語言模型對抗性提示安全防御指南

對抗性提示工程 學習目標 理解大語言模型中對抗性提示的風險與防御機制,掌握提示注入、提示泄露和越獄攻擊的檢測方法,培養安全防護意識。 相關知識點 對抗性攻擊類型防御技術 學習內容 1 對抗性攻擊類型 1.1 提示注入 提示注入旨在通過使用巧妙…

避不開的數據拷貝(2)

接著上周未完的話題 避不開的數據拷貝。 既然處理器是通用機器,就沒有專屬數據,所以數據都要從別處調來,這就涉及到了數據搬運,就有了外設的概念。由于不同外設和處理器一起共享數據存儲,時間會花在兩方面&#xff1a…

娃哈哈經銷商“大洗牌”:砍掉年銷300萬以下經銷商

文 | 大力財經據第一財經報道,娃哈哈在宗馥莉“鐵腕”策略推動下,正經歷經銷商體系的重大變革,陸續砍掉年銷低于300萬元的經銷商,方式有時頗為激進,“一刀切”的做法引發諸多爭議,部分經銷商反饋存在款項未…

drippingblues靶機通關練習筆記

前言 將靶機導入到vmware虛擬機上 靶機下載地址:https://download.vulnhub.com/drippingblues/drippingblues.ova 將網段都設置為nat 信息收集 ip端口掃描 netdiscover -r 192.168.25.1/24 --確定ip nmap -A -p- 192.168.25. kalid的ip:1…

QT第三講- 機制、宏、類庫模塊

文章目錄 ?? 一、Qt核心機制與類庫 ?? 1. 元對象系統(Meta-Object System) ? 2. 信號與槽(Signals & Slots) ? 通信機制 ?? 3. 屬性系統(Property System) 動態屬性 例程 類的附加信息 Q_CLASSINFO 例程 ?? 二、全局定義與容器 ?? 1. 全局數據類型與函數…

(LeetCode 每日一題) 869. 重新排序得到 2 的冪 (哈希表+枚舉)

題目&#xff1a;869. 重新排序得到 2 的冪 思路&#xff1a;哈希表枚舉。先預處理出所有的2的冪數&#xff0c;用哈希表來存儲。 C版本&#xff1a; class Solution { public:// 哈希表存儲所有 2的冪數 按升序排列的形式unordered_set<string> st;// 預處理出所有的2…

WebAssembly技術詳解:從瀏覽器到云原生的高性能革命

引言&#xff1a;WebAssembly的誕生與使命 2015年&#xff0c;當Mozilla、Google、Microsoft和Apple四大瀏覽器廠商聯合發布WebAssembly&#xff08;Wasm&#xff09;技術預覽時&#xff0c;業界尚未意識到這將開啟Web性能的新紀元。作為繼HTML、CSS、JavaScript之后的第四種We…

性能解析案例

異步io是內核fd與應用程序直接的關系io 多路復用1.檢測io是否就緒2.read/write消息隊列kafka&#xff1a;1.典型應用 &#xff1a;異步處理&#xff0c;系統解耦&#xff0c;流量削峰&#xff0c;日志處理2.核心原理&#xff1a;kafka體系結構以及讀寫流程3.具體操作&#xff1…

青龍峽拔韭菜

我們一年四季&#xff0c;除了冬天不往山里進&#xff0c;其余季節&#xff0c;只要天氣允許&#xff0c;我們都會進山。在山里拔韭菜&#xff0c;是我們百做不煩的一件事。今年大旱&#xff0c;從五月份上山找韭菜&#xff0c;沒有如愿。直到入秋后&#xff0c;我們再次去青龍…

5、docker鏡像管理命令

1、命令總覽命令&#xff08;含關鍵參數&#xff09;作用出現頻率備注docker buildx build --platform … -t … --push .一次構建并推送多平臺鏡像高頻需先 docker buildx create --usedocker buildx build -o typedocker,destxxx.tar .構建后離線導出 tar 包中頻只導出單平臺…

阿里云ECS云服務器臨時升級帶寬方法

阿里云ECS云服務器臨時升級帶寬方法一、背景與需求二、原理三、操作步驟步驟 0: 準備工作步驟 1: 創建彈性網卡 (ENI)步驟 2: 創建并綁定彈性公網IP (EIP)步驟 3: SSH登錄ECS并切換到高速通道 (eth1)步驟 4: 執行你的高帶寬任務步驟 5: 任務完成&#xff0c;切回默認網卡 (eth0…

Java語言簡介

一.Java語言的起源 Java語言的前身是Oka語言,是美國Sun Microsystems公司于1991年推出的,僅限于公司內部使用的語言。1995年,Sun公司將Oak語言更名為Java語言,并正式向公眾推出。這之后,Java語言不斷更新,其類庫越來越豐富,性能逐步提升,應用領域也顯著拓展,已成為當今…

VUE+SPRINGBOOT從0-1打造前后端-前后臺系統-視頻列表與視頻播放

在現代Web開發中&#xff0c;視頻播放功能已成為許多網站的基本需求。本文將基于Vue.js框架&#xff0c;詳細講解如何實現一個視頻列表與播放器交互的功能模塊。這個組件可以讓用戶點擊列表中的視頻項來播放對應的視頻&#xff0c;并支持再次點擊關閉播放器。功能概述我們實現的…

詳解 Seaborn:讓數據可視化更簡單高效的 Python 庫

在數據科學領域&#xff0c;可視化是理解數據、挖掘規律的重要手段。今天要為大家介紹的 Seaborn 庫&#xff0c;正是數據可視化領域的一把 “利器”。它基于 Matplotlib 開發&#xff0c;卻憑借更簡潔的接口和更美觀的默認樣式&#xff0c;成為眾多數據分析師的首選工具。下面…

Cesium1.95中如何高效管理 1500 個高頻實體

一、建議&#xff1a;不要頻繁創建/銷毀&#xff0c;而是復用對象&#xff1b;????使用 CallbackProperty更新位置而不是刪了重建&#xff1b;????對大量 Billboard / Polyline / Label&#xff0c;優先使用對應的 *Collection&#xff0c;然后批量更新&#xff1b;??…

全面了解機器語言之kmeans

深入理解 KMeans 聚類算法&#xff1a;原理、實現與應用在機器學習領域&#xff0c;聚類算法作為無監督學習的核心技術之一&#xff0c;一直以來都是數據挖掘和模式識別的重要工具。其中&#xff0c;KMeans 算法以其簡潔的原理、高效的計算性能和廣泛的適用性&#xff0c;成為最…

納米陶瓷與光子集成:獵板PCB定義下一代VR硬件的技術藍圖

虛擬現實&#xff08;VR&#xff09;設備正從“視覺沉浸”向“多感官無感交互”演進&#xff0c;其底層PCB技術面臨帶寬、算力密度與動態可靠性的三重挑戰。作為國內高端PCB技術的引領者&#xff0c;??獵板PCB??以材料革新、光電子融合與智能響應為核心&#xff0c;構建了適…