操作系統進程管理筆記

1. 進程的基本概念

1.1 進程的定義

進程就是運行中的程序。程序本身是沒有生命周期的,它只是存在磁盤上面的一些指令(也可能是一些靜態數據)。是操作系統讓這些字節運行起來,讓程序發揮作用。

1.2 CPU的時分共享

操作系統通過讓一個進程只運行一個時間片,然后切換到其他進程,提供了存在多個虛擬CPU的假象。這就是時分共享(time sharing)CPU技術,允許用戶如愿運行多個并發進程。潛在的開銷就是性能損失,因為如果CPU必須共享,每個進程的運行就會慢一點。

1.3 進程的機器狀態

進程的機器狀態包括:

  • 內存:進程可以訪問的內存(稱為地址空間,address space)
    • 指令存在內存中
    • 正在運行的程序讀取和寫入的數據也在內存中
  • 寄存器
    • 程序計數器(Program Counter,PC):告訴我們程序當前正在執行哪個指令
    • 棧指針(stack pointer)和幀指針(frame pointer):用于管理函數參數棧、局部變量和返回地址

寄存器結構圖

2. 程序與進程的區別

  • 程序(Program):一個靜態實體,通常是以可執行文件形式存儲在磁盤上的指令和數據的集合
  • 進程(Process):程序的動態執行實例,運行時加載到內存中,擁有獨立的地址空間、執行狀態和系統資源

簡單來說,程序是靜態的"藍圖",而進程是程序被激活后的"活體"。

3. 操作系統啟動并運行程序的過程

3.1 加載程序到內存

  1. 定位可執行文件:根據用戶命令或系統調用找到磁盤上的可執行文件
  2. 讀取文件頭部
    • 入口點(Entry Point):程序開始執行的地址
    • 段信息:代碼段、數據段等的地址和大小
  3. 從磁盤讀取字節
    • 代碼段:包含程序的指令,通常是只讀的
    • 數據段:包含初始化的全局變量和靜態變量
    • BSS段:包含未初始化的全局變量
  4. 分配虛擬地址空間:為進程分配獨立的虛擬地址空間
  5. 按需加載(可選):延遲加載優化性能

3.2 分配堆棧和堆

  • 堆棧(Stack):存儲函數調用信息、局部變量等
  • 堆(Heap):用于動態內存分配

3.3 設置執行環境

  • 寄存器初始化
  • 命令行參數和環境變量
  • 文件描述符

3.4 創建進程控制塊(PCB)

記錄進程元數據,包括:

  • 進程ID(PID)
  • 進程狀態
  • 內存管理信息
  • 打開的文件描述符

3.5 調度執行

進程被加入就緒隊列,等待CPU調度

4. 進程狀態

進程的三種基本狀態:

  • 運行(running):在處理器上運行,執行指令
  • 就緒(ready):準備好運行,但操作系統選擇不在此時運行
  • 阻塞(blocked):執行了某種操作,直到發生其他事件時才會準備運行
    從就緒到運行意味著該進程已經被調度(scheduled)。從運行轉移到就緒意味著該進程已經取消調度(descheduled)。一旦進程被阻塞(例如,通過發起 I/O 操作),OS 將保持進程的這種狀態,直到發生某種事件(例如,I/O 完成)。此時,進程再次轉入就緒狀態(也可能立即再次運行,如果操作系統這樣決定)。

image.png
寄存器上下文將保存其寄存器的內容。當一個進程停止時,它的寄存器將被保存到這個內存位置。==通過恢復這些寄存器(將它們的值放回實際的物理寄存器中)?,==操作系統可以恢復運行該進程。我們將在后面的章節中更多地了解這種技術,它被稱為上下文切換(contextswitch)?。

5. 進程管理系統調用

5.1 fork系統調用

  • 創建一個新進程,作為調用進程的副本
  • 子進程復制父進程的地址空間、PCB等
  • 父進程返回子進程PID,子進程返回0
#include <stdio.h>      // 包含標準輸入輸出庫,提供 printf() 等函數
#include <stdlib.h>     // 包含標準庫,提供 exit() 函數等
#include <unistd.h>     // 包含 UNIX 標準函數聲明,提供 fork()、getpid() 等int main(int argc, char *argv[])  // 程序入口,argc/argv 用于獲取命令行參數{// 在創建子進程之前,先打印當前進程的 PID(進程標識符)printf("hello world (pid:%d)\n", (int)getpid());// 調用 fork(),創建一個新進程(子進程)int rc = fork();if (rc < 0) {            // fork 返回值小于 0,表示創建子進程失敗fprintf(stderr, "fork failed\n");  // 向標準錯誤輸出錯誤信息exit(1);            // 退出程序,并返回非零狀態碼表示異常} else if (rc == 0) {    // fork 返回值等于 0,表示當前是子進程// 子進程執行的代碼路徑printf("hello, I am child (pid:%d)\n", (int)getpid());} else {                 // fork 返回值大于 0,表示當前是父進程// rc 存儲的是子進程的 PIDprintf("hello, I am parent of %d (pid:%d)\n",rc, (int)getpid());}return 0;  // 程序正常退出,返回值 0}

image.png
子進程并不是完全拷貝了父進程。具體來說,雖然它擁有自己的地址空間(即擁有自己的私有內存)?、寄存器、程序計數器等,但是它從fork()返回的值是不同的。父進程獲得的返回值是新創建子進程的PID,而子進程獲得的返回值是0。
系統顯示父進程先執行,但是這是隨機的,CPU調度程序(scheduler)決定了某個時刻哪個進程被執行

5.2 wait系統調用

  • 父進程阻塞直到子進程結束
  • 返回已結束子進程的PID
#include <stdio.h>      // 標準輸入輸出,提供 printf()
#include <stdlib.h>     // 標準庫,提供 exit()
#include <unistd.h>     // POSIX API,提供 fork()、getpid()
#include <sys/wait.h>   // 等待子進程,提供 wait()int main(int argc, char *argv[])
{// 在 fork 之前,先打印當前進程(父進程)的 PIDprintf("hello world (pid:%d)\n", (int)getpid());// 創建一個新進程;父進程中 rc > 0,子進程中 rc == 0,失敗時 rc < 0int rc = fork();if (rc < 0) {// fork 調用失敗fprintf(stderr, "fork failed\n");exit(1);} else if (rc == 0) {// 子進程執行這里的代碼printf("hello, I am child (pid:%d)\n", (int)getpid());} else {// 父進程執行這里的代碼// wait(NULL) 阻塞直到任意子進程結束,返回值是已結束子進程的 PIDint wc = wait(NULL);printf("hello, I am parent of %d (wc:%d) (pid:%d)\n",rc, wc, (int)getpid());}return 0;  // 正常退出
}

image.png

5.3 exec系統調用

  • 在當前進程中加載并執行新程序
  • 替換當前地址空間
  • 重置堆棧、堆和寄存器
#include <stdio.h>      // 標準輸入輸出,提供 printf()
#include <stdlib.h>     // 標準庫,提供 exit()
#include <unistd.h>     // POSIX API,提供 fork()、execvp()、getpid()
#include <string.h>     // 字符串操作,提供 strdup()
#include <sys/wait.h>   // 等待子進程,提供 wait()int main(int argc, char *argv[])
{// 程序啟動時打印當前進程(父進程)的 PIDprintf("hello world (pid:%d)\n", (int)getpid());// 創建子進程:父進程 rc>0,子進程 rc==0,失敗時 rc<0int rc = fork();if (rc < 0) {// fork 失敗,打印錯誤并退出fprintf(stderr, "fork failed\n");exit(1);}else if (rc == 0) {// 子進程執行此路徑printf("hello, I am child (pid:%d)\n", (int)getpid());// 準備 execvp 的參數數組// myargs[0] 指定要運行的程序名 "wc"// myargs[1] 指定要處理的文件 "p3.c"// myargs[2] 置 NULL,標記參數數組結束char *myargs[3];myargs[0] = strdup("wc");      myargs[1] = strdup("p3.c");   myargs[2] = NULL;// 用 execvp 替換當前子進程映像,執行 word count 程序execvp(myargs[0], myargs);// 如果 execvp 返回,說明執行失敗,才會走到這里perror("execvp failed");exit(1);}else {// 父進程執行此路徑// wait(NULL) 阻塞直到任意子進程結束,返回已結束子進程的 PIDint wc = wait(NULL);// 打印父進程信息,rc 是子進程的 PID,wc 是 wait 返回的 PIDprintf("hello, I am parent of %d (wc:%d) (pid:%d)\n",rc, wc, (int)getpid());}return 0;  // 正常退出
}

要點說明

  • strdup():復制字符串并返回指向新內存的指針,用于給 execvp 準備參數。
  • execvp():用指定程序替換當前進程映像,不返回成功;如果失敗,會返回 -1,此時應打印錯誤并退出。
  • wait(NULL):父進程阻塞直到子進程結束,避免子進程成為僵尸。

image.png

image.png

6. 安全機制:地址空間布局隨機化(ASLR)

6.1 ASLR的定義

ASLR是一種安全技術,通過隨機化進程的內存地址布局,防止攻擊者利用已知的內存地址執行惡意代碼。

6.2 工作原理

隨機化內存布局的關鍵區域:

  • 堆棧(Stack)
  • 堆(Heap)
  • 可執行代碼(Text Segment)
  • 動態鏈接庫(Shared Libraries)

6.3 優缺點

優點

  • 提升安全性
  • 兼容性強

缺點

  • 非絕對防御
  • 輕微性能開銷

7. 內存分配:堆和棧

7.1 棧(Stack)

保存內容

  • 局部變量
  • 函數參數
  • 返回地址
  • 棧幀

特點

  • 先進后出(LIFO)
  • 速度快
  • 大小有限

7.2 堆(Heap)

保存內容

  • 動態分配的對象
  • 全局數據(部分情況)

特點

  • 手動管理
  • 靈活性高
  • 速度較慢
  • 可能產生碎片

7.3 堆和棧的區別對比

特性棧(Stack)堆(Heap)
分配方式自動分配和釋放手動分配和釋放
存儲內容局部變量、函數參數動態分配的數據
生命周期隨函數調用結束而銷毀在手動釋放前一直存在
大小限制容量較小容量較大
速度操作更快操作較慢

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

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

相關文章

Python中random庫的應用

文章目錄 一、random 庫常用函數二、條件語句 隨機數示例1&#xff1a;隨機決定程序分支示例2&#xff1a;模擬概率事件 三、循環語句 隨機數示例1&#xff1a;循環直到滿足隨機條件示例2&#xff1a;隨機次數循環 四、隨機操作數據結構示例1&#xff1a;隨機打亂列表順序示例…

密碼學貨幣混幣器詳解及python實現

目錄 一、前言二、混幣器概述2.1 混幣器的工作原理2.2 關鍵特性三、數據生成與預處理四、系統架構與流程五、核心數學公式六、異步任務調度與 GPU 加速七、PyQt6 GUI 設計八、完整代碼實現九、自查測試與總結十、展望摘要 本博客聚焦 “密碼學貨幣混幣器實現”,以 Python + P…

各種各樣的bug合集

一、連不上數據庫db 1.可能是密碼一大包東西不對&#xff1b; 2.可能是里面某個port和數據庫不一樣&#xff08;針對于修改了數據庫但是連不上的情況&#xff09;&#xff1b; 3.可能是git代碼沒拉對&#xff0c;再拉一下代碼。? 二、沒有這個包 可能是可以#注釋掉。? …

面陣相機中M12鏡頭和遠心鏡頭的區別及性能優勢

以下是關于面陣相機中M12鏡頭和遠心鏡頭的區別及性能優勢的詳細分析&#xff0c;結合知識庫內容整理如下&#xff1a; 一、M12鏡頭與遠心鏡頭的核心區別 1. 設計原理與光學特性 特性M12鏡頭遠心鏡頭光學設計標準鏡頭設計&#xff0c;無特殊光學校正&#xff0c;依賴傳統光路。…

從內核到應用層:深度剖析信號捕捉技術棧(含sigaction系統調用/SIGCHLD回收/volatile內存屏障)

Linux系列 文章目錄 Linux系列前言一、進程對信號的捕捉1.1 內核對信號的捕捉1.2 sigaction()函數1.3 信號集的修改時機 二、可重入函數三、volatile關鍵字四、SIGCHLD信號 前言 Linux系統中&#xff0c;信號捕捉是指進程可以通過設置信號處理函數來響應特定信號。通過信號捕捉…

DDD領域驅動與傳統CRUD

DDD 是一套 應對復雜業務系統 的設計方法論&#xff0c;核心是 讓代碼直接映射業務邏輯&#xff0c;避免技術實現與業務需求脫節。 關鍵區別&#xff1a; 傳統開發&#xff1a;根據數據庫表寫 CRUD&#xff08;技術驅動&#xff09;。DDD&#xff1a;根據業務行為建模&#xf…

20. git diff

基本概述 git diff的作用是&#xff1a;比較代碼差異 基本用法 1.工作區 VS 暫存區 git diff [file]2.暫存區 VS 最新提交 git diff --staged [file] # 或 git diff --cached [file]3.工作區 VS 最新提交 git diff HEAD [file]高級用法 1.比較兩個提交間的差異 git dif…

大模型面經 | 春招、秋招算法面試常考八股文附答案(五)

大家好,我是皮先生!! 今天給大家分享一些關于大模型面試常見的面試題,希望對大家的面試有所幫助。 往期回顧: 大模型面經 | 春招、秋招算法面試常考八股文附答案(RAG專題一) 大模型面經 | 春招、秋招算法面試常考八股文附答案(RAG專題二) 大模型面經 | 春招、秋招算法…

Sql刷題日志(day5)

面試&#xff1a; 1、從數據分析角度&#xff0c;推薦模塊怎么用指標衡量&#xff1f; 推薦模塊主要目的是將用戶進行轉化&#xff0c;所以其主指標是推薦的轉化率推薦模塊的指標一般都通過埋點去收集用戶的行為并完成相應的計算而形成相應的指標數據&#xff0c;而這里的驅動…

封裝 element-ui 二次彈框

author 封裝 element-ui 彈框 param text 文本內容 &#xff08;不傳默認顯示 確定執行此操作嗎&#xff1f; &#xff09; param type 彈框類型&#xff08;不傳默認warning類型&#xff09; param title 彈框標題&#xff08;不傳默認顯示 提示 &#xff09; export fun…

【Rust 精進之路之第12篇-生命周期·入門】為何需要與顯式標注 (`‘a`):讓編譯器讀懂引用的“有效期”

系列: Rust 精進之路:構建可靠、高效軟件的底層邏輯 作者: 碼覺客 發布日期: 2025-04-20 引言:懸垂引用的“幽靈”與編譯器的“偵探” 在前面的章節中,我們深入學習了 Rust 的所有權系統,以及如何通過引用 (& 和 &mut) 進行借用,從而在不轉移所有權的情況下安…

[密碼學實戰]CTF競賽高頻加密與解密技術詳解

CTF競賽高頻加密與解密技術詳解 一、CTF加密體系全景圖 在CTF密碼學挑戰中&#xff0c;加解密技術主要分為四大戰域&#xff1a; #mermaid-svg-lmm07BXqYAGYjymI {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lm…

docker.desktop下安裝普羅米修斯prometheus、grafana并看服務器信息

目標 在docker.desktop下先安裝這三種組件,然后顯示當前服務的CPU等指標。各種坑已踩,用的是當前時間最新的鏡像 核心關系概述 組件角色依賴關系Prometheus開源監控系統,負責 數據采集、存儲、查詢及告警。依賴 Node-Exporter 提供的指標數據。Node-Exporter專用的 數據采集…

《MySQL:MySQL表的內外連接》

表的連接分為內連接和外連接。 內連接 內連接實際上就是利用where子句對兩種表形成的笛卡爾積進行篩選&#xff0c;之前的文章中所用的查詢都是內連接&#xff0c;也是開發中使用的最多的連接查詢。 select 字段 from 表1 inner join 表2 on 連接條件 and 其他條件&#xff1…

實現SpringBoot底層機制【Tomcat啟動分析+Spring容器初始化+Tomcat 如何關聯 Spring容器】

下載地址&#xff1a; https://download.csdn.net/download/2401_83418369/90675207 一、搭建環境 創建新項目 在pom.xml文件中導入依賴 &#xff08;一定要刷新Maven&#xff09;排除內嵌的Tomcat&#xff0c;引入自己指定的Tomcat <?xml version"1.0" enco…

從零開始構建微博爬蟲:實現自動獲取并保存微博內容

從零開始構建微博爬蟲&#xff1a;實現自動獲取并保存微博內容 前言 在信息爆炸的時代&#xff0c;社交媒體平臺已經成為信息傳播的重要渠道&#xff0c;其中微博作為中國最大的社交媒體平臺之一&#xff0c;包含了大量有價值的信息和數據。對于研究人員、數據分析師或者只是…

Uniapp微信小程序:輕松獲取用戶頭像和昵稱

參考文獻&#xff1a;Uniapp微信小程序&#xff1a;輕松獲取用戶頭像和昵稱-百度開發者中心 (baidu.com) uni.login({ provider: weixin, success: function (loginRes) { console.log(loginRes.authResult); // 打印登錄憑證 // 使用登錄憑證獲取用戶信息 uni.getUserInfo({ …

【自然語言處理與大模型】大模型(LLM)基礎知識③

&#xff08;1&#xff09;大模型的“7B”是什么意思&#xff1f; "B"通常代表“Billion”&#xff0c;即十億。因此&#xff0c;當提到7B時&#xff0c;指的是該模型擁有7 billion&#xff08;70億&#xff09;個參數。 &#xff08;2&#xff09;模型后面標的“ins…

聊聊自動化用例的維護

自動化測試中的農藥悖論&#xff1a;為何長期維護至關重要 自動化測試常被視為"一次編寫&#xff0c;永久有效"的解決方案&#xff0c;但隨著時間的推移&#xff0c;即使設計最精良的測試套件也會逐漸失效。這種現象被稱為農藥悖論&#xff08;Pesticide Paradox&am…

微幀Visionular斬獲NAB Show 2025年度產品獎

在本月剛結束的NAB Show 2025展會上&#xff0c;全球領先的視頻編碼與AI超高清服務提供商微幀Visionular大放異彩&#xff0c;其核心產品AI-driven Video Compression&#xff08;AI視頻智能編碼引擎&#xff09;不僅在展會中吸引了眾多行業目光&#xff0c;更憑借其卓越的編碼…