進程是什麼
進程故名思意就是在計算機中正在進行中的程序。
我們知道操作系統對計算機中的所有程序是 先描述、在組織 。那麼計算機中是如何對進程進行描述的?
描述進程-PCB
PCB(process control block)進程管理塊。在計算機中,進程被放在一個叫做進程控制塊的數據結構中,可以理解爲進程屬性的集合。(Linux操作系統下的PCB是 task_struct :Linux 內核中的一種數據結構,被轉載到RAM中 包含着進程的信息)
task_struct 內容:
- 標識符:描述進程的唯一標識符,用來區別其他進程;
- 狀態:任務狀態,退出信號,退出代碼等;
- 優先級:相對於其他進程的優先級;
- 程序計數器:存放着程序中即將要被執行的下一跳指令;
- 內存指針:包括程序代碼和進程相關數據的指針,還有和其他進程共享的內存塊的指針;
- 上下文數據:進程執行時處理器的寄存器中的數據
- I / O 狀態信息:包含顯示的I / O請求,分配給進程的 I / O 設備和被進程使用的文件列表;
- 記賬信息:可能包括處理器時間總和,使用的時鐘數總和,時間限制,記賬號;
組織進程
先描述、再組織,怎麼組織呢?所有運行在系統裏的進程都已 task_struct 鏈表的形式存在內核裏;
CPU分時機制:切換調度進程,每個進程之運行很短的時間(時間片);
查看進程
在系統文件 /proc 中:
還可以通過命令 ps aux 來查看進程的詳細信息:
進程描述符
上面的表中有一項叫做 PID 每一個進程都不一樣,這個 PID叫做進程描述符。(PPID:父進程的 id)
通過系統調用獲取進程標識符
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(){
printf("pid:%d",getpid());
printf("ppid:%d",getppid());
return 0;
}
創建進程
通過複製調用進程(父進程)創建一個新的進程(子進程)。
複製父進程的PCB,和父進程運行相同的代碼,一樣的運行位置,處理一樣的數據。
父子進程之間 代碼共享,數據獨有(虛擬內存地址相同,但是實際的物理地址不同)
#include <unistd.h>
pid_t fork(void);
/*
創建成功:
父進程:返回子進程PID
子進程:返回 0
創建失敗:
父進程:返回 -1
*/
創建的子進程有什麼用
1、分攤壓力,CPU資源足夠的情況下父子進程同時進行處理,效率更高
2、完成其他的任務(要進行分流)
查看進程狀態
常見的進程狀態有:R(運行態)、S(可中斷睡眠態)、D(不可中斷睡眠態)、T(停止狀態)、Z(殭屍態)、X(死亡態)
ps aux 命令裏面的 STAT 就是指該進程的狀態;
殭屍進程(Z)
進程的僵死狀態是一種非常特殊的狀態,它的形成原因:
- 當子進程退出而父進程沒有獲取到子進程的退出狀態,此時子進程的數據無法被釋放,就成爲了殭屍進程;
可見,無論對於哪種情況,只要父進程沒有正確的處理子進程的返回信息,子進程都將停留在殭屍態,佔據着內核資源;
殭屍進程的危害:1、佔用內存,造成內存浪費,導致內存泄漏;2、佔用系統資源;
解決殭屍進程:只有結束了其父進程,殭屍進程纔會停止;
當父進程先於子進程退出後,子進程也會處於殭屍狀態,但是會被1號進程回收,PPID變爲1,此時稱爲孤兒進程;
進程優先級
CPU資源分配的先後順序,就是指進程的優先權。優先權的高低,對於配置多任務環境的Linux很有用,可以大大改善系統性能。
幾個重要的信息:
- UID:執行者的身份
- PID:這個進程的ID
- PPID:父進程的ID
- PRI:代表這個進程的優先級,PRI值越小,優先級越高
- NI:代表這個進程的 nice 值
PRI 的計算方法:PRI(新) = PRI(舊) + nice; nice 的取值範圍是:-20 ~ 19 ,一共只有 40 個級別;
可以通過 top 命令來修改進程的優先級:top --> "r" --> 輸入進程的PID --> 輸出新的 nice 值