Linux進程概念
馮諾依曼體系
馮諾依曼體系結構(Von Neumann Architecture)是現代計算機設計的奠基石,由數學家約翰·馮·諾依曼于1945年提出。這一架構徹底改變了早期計算機“硬件即程序”的設計方式,使得計算機可以靈活地運行不同程序,開啟了可編程計算時代。
🧠 核心思想:存儲程序原理
馮諾依曼結構的最大創新是將程序和數據統一存儲在同一個存儲器中,并通過控制器逐條讀取指令執行。這種設計使得程序可以像數據一樣被修改、傳輸和存儲。
🧱 五大組成部分
部件 | 功能說明 |
---|---|
運算器(ALU) | 執行算術和邏輯運算,如加減乘除、與或非等操作 |
控制器(CU) | 負責指令的讀取、譯碼和控制其他部件的操作流程 |
存儲器 | 存儲程序指令和數據,通常是 RAM(內存)和 ROM(只讀存儲器) |
輸入設備 | 將外部信息輸入計算機,如鍵盤、鼠標、攝像頭等 |
輸出設備 | 將計算結果輸出到外部,如顯示器、打印機、揚聲器等 |
五大組成部分結構體系圖 | |
![]() | 1. 這里的存儲器指的是內存(具有掉電遺失的性質),而磁盤是外設是擁有永久性存儲的能力 2. CPU是不會直接和外設進行交流,所有外設的輸入輸出數據只能寫入到內存之中去 |
🔁 工作流程介紹
- 從存儲器中取指令
- 控制器譯碼指令
- 根據指令操作數據
- 運算器執行運算
- 結果寫回存儲器或輸出設備
操作系統
🧠 操作系統概念
操作系統(Operating System,簡稱 OS)是計算機系統中最基本、最核心的系統軟件。它負責管理計算機的硬件資源,并為用戶和應用程序提供運行環境。
? 簡單定義:
操作系統是管理計算機硬件與軟件資源的中間層,它協調各個組件的運行,使用戶和程序能夠高效、安全地使用計算機。
- 內核(進程管理,內存管理,文件管理,驅動管理)
- 其他程序(函數庫,shell程序)
🎯 操作系統的設計目的
操作系統的設計目的可以從兩個方向理解:
🔽 對下:管理硬件資源(手段)
- 管理 CPU:調度進程、分配時間片
- 管理內存:分配空間、提供虛擬內存
- 管理設備:通過驅動程序控制硬件
- 管理文件系統:組織數據、提供訪問接口
操作系統屏蔽了底層硬件的復雜性,為上層應用提供統一的訪問方式。
🔼 對上:服務用戶和應用程序(目的)
- 提供程序運行環境
- 提供系統調用接口(如文件讀寫、進程創建)
- 提供圖形界面或命令行交互方式
- 提供安全性、穩定性和資源隔離
就像銀行柜員是用戶與后臺系統之間的橋梁,操作系統是用戶程序與硬件之間的“服務窗口”。
- 操作系統管理硬件的一個過程就是
- 先將其利用結構體進行描述
- 然后利用鏈表或者其他的更高效的數據結構進行管理組織
🧱 操作系統的定位
在整個計算機系統架構中,操作系統處于中間層:
用戶程序↑
系統調用 / 庫函數↑
操作系統(內核)↑
硬件(CPU、內存、設備)
🧩 小結
維度 | 內容說明 |
---|---|
概念 | 管理軟硬件資源的系統軟件 |
設計目的 | 對下管理硬件,對上服務用戶 |
定位 | 計算機系統的中間層,是用戶與硬件之間的橋梁 |
核心功能 | 進程管理、內存管理、文件系統、設備驅動、安全性 |
接下來我們來了解進程的概念
- 基本概念:就是一個執行的實例,一個正在運行的程序
- 內核觀點:擔當分配系統資源的實體,在這里我的理解是內存資源
描述進程PCB(process control block)
task_struct-PCB的一種
- 在Linux中描述進程的結構體叫做task_struct。
- task_struct是Linux內核的一種數據結構,它會被裝載到RAM(內存)里并且包含著進程的信息。
簡單理解就是,當我寫了一個小程序,此時執行,現在這個小程序是在內存之中被執行的,而他的可執行文件則在硬盤當中。
但是電腦內存當中肯定不止這一個執行的程序也就是進程,有太多的加載進來的程序,操作系統肯定要進行管理。
所以在這里使用task_struct,也就是先對其進行描述再進行管理
所謂的對進程進行管理,也就轉變成了對PCB進行相關的管理
而對進程管理-> 也就轉化成了對鏈表的增刪查改- 簡要介紹一下這個task_struct中存儲了以下信息
🧱 task_struct 的核心字段
分類 | 字段示例 | 說明 |
---|---|---|
🔖 標識信息 | pid , tgid , ppid | 進程號、線程組號、父進程號 |
📍 狀態信息 | state , exit_code | 當前狀態(運行、等待、僵死等) |
🎛? 調度信息 | priority , policy , counter | 優先級、調度策略、時間片 |
🧠 內存信息 | mm , active_mm | 指向進程的內存描述結構 |
🧵 線程信息 | thread | 保存寄存器上下文、棧指針等 |
📂 文件系統信息 | files , fs | 打開的文件、文件系統上下文 |
🔗 鏈接信息 | parent , children , sibling | 父子進程關系 |
🔔 信號處理 | signal , blocked , sigpending | 信號處理相關字段 |
📊 統計信息 | utime , stime , start_time | 用戶態/內核態時間、啟動時間 |
查看進程
1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 int main()5 {6 // 引入子進程的概念,觀察進程現象7 pid_t id = fork();8 printf("我是一個進程,pid: %d, ppid:%d, id:%d\n",getpid(), getppid(), id);9 // 觀察進程狀態10 //while(1)11 //{12 // printf("我是一個進程,pid: %d, ppid:%d\n",getpid(), getppid());13 // sleep(1); 14 //}15 return 0;16 }
在這里先忽略fork,可以看到執行的程序結果pid是16802,使用指令查看,在這張圖片里顯示的最后一個進程是我們使用了grep查找16802可以忽略
- 進程id (PID)
- 父進程id(PPID)
🧠 fork()
的概念
fork()
是 Linux 和類 Unix 系統中用于創建新進程的系統調用。它的核心作用是:
復制當前進程,生成一個幾乎完全一樣的子進程。
這個“復制”并不是簡單的拷貝,而是通過一種叫做 寫時復制(Copy-On-Write, COW) 的機制來優化性能。
🧱 基本語法
#include <unistd.h>pid_t fork(void);
- 返回值:
- > 0:父進程,返回的是子進程的 PID
- = 0:子進程
- < 0:創建失敗,返回 -1,并設置
errno
🧪 示例代碼
#include <stdio.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork failed");return 1;} else if (pid == 0) {// 子進程printf("Hello from child! PID = %d\n", getpid());} else {// 父進程printf("Hello from parent! Child PID = %d\n", pid);}return 0;
}
🧾 輸出可能是:
Hello from parent! Child PID = 12345
Hello from child! PID = 12345
注意:父子進程的執行順序不確定,由操作系統調度決定。
🔍 fork 的工作原理
- 復制進程上下文:包括代碼段、數據段、堆、棧等
- 獨立 PID:子進程擁有自己的進程號
- 共享文件描述符:初始時父子進程共享打開的文件
- 地址空間獨立:雖然初始共享內存頁,但修改時會觸發復制(COW)
🧩 常見用途
- 創建后臺任務或守護進程
- 實現并行計算
- 與
exec()
結合,執行新程序(如 shell 命令) - 構建多進程服務器(如 Apache)
?? 注意事項
- 必須處理返回值,否則容易邏輯混亂
- 避免僵尸進程:父進程應使用
wait()
或waitpid()
等待子進程結束 - 資源消耗:雖然 COW 優化了性能,但頻繁 fork 仍可能影響系統穩定性