進程基礎
a.從程序到進程
1.內核將程序讀入內存,為程序鏡像分配內存空間。
2.內核為該進程分配進程標識符PID。
3.內核為該進程保存PID及相關的進程狀態信息。
b.程序格式ELF
Executable and Linkable Format文件格式,一種用于二進制文件、可執行文件、目標代碼、共享庫和核心轉儲格式文件。
查看程序(ELF):readelf -S 文件名
查看進程空間大小:size 文件名
c.虛擬存儲器/虛擬地址空間
進程的概念:
進程與程序的區別
1.進程是動態的,而程序是靜態的
2.進程有生命周期,二程序是指令集合
3.一個進程只能對應一個程序,而一個程序可以改對應多個進程
進程的狀態可以分為三類:
1.就緒(Ready)
2.運行(Running)
3.阻塞(Blocked)
進程腳本:
###如何查看進程
Windows:
tasklist:tasklist/FI *PID eq進程PID*
Linux:
1.ps:USER(用戶)PID(進程ID)%CPU(進程占用的CPU百分比)%MEM(占用內存的百分比)VSZ(進程虛擬大小)RSS(常駐內存[內存中的頁的數量])TTY(終端ID)STAT(啟動進程的時間)TIME(進程消耗CPU的時間)COMMAND(命令的名稱和參數)
查看某些進程
ps -p 進程PID
ps -C 命令行
查看進程
ps -aux BSD風格 a:終端上所有用戶的進程;u:以用戶為中心顯示詳情信息;x:無終端進程
ps -ef System風格 e:所有進程;f:樹狀顯示
ps進程狀態顯示:D(不可中斷Uninterruptible[usually IO]) R(正在運行,或在隊列中的進程) S(處于休眠狀態) T(停止或被追蹤) Z(僵尸進程) X(死掉的進程) <(高優先級) n(低優先級) s(包含子進程) +(位于后臺的進程組)
2.pstree:以樹狀圖的方式展現進程之間的派生關系(安裝:yum install psmisc)
3.top:實時顯示系統中各個進程的資源占用(類似Windows的任務管理器)
###如何創建進程
Windows:
程序名
Linux:
程序名
###如何殺死進程
Windows:
taskkill /F /PID 進程標識
taskkill /F /IM 程序名
Linux:
kill 進程標識PID
進程文件
/proc/
進程操作
###進程標識pid
類比:身份證號(計算機是數學學霸,經常使用數字起名,例如:IP地址)
獲取PID
pid_t getpid() 獲取當前進程ID
pid_t getppid() ? 獲取當前進程父進程ID
###如何創建進程
區別:
fork()復制父進程
system()阻塞父進程
exec()替換原進程
pid_t fork()
返回值
-1:失敗
0:子進程邏輯控制流
其他(子進程PID):父進程邏輯控制流
特點
調用一次,返回兩次
相同但是獨立的地址空間
并發執行
并發concurrency
兩個或多個進程在同時存在
單核
進程指令同時或交錯執行
并行parallellism
共享文件
本質:復制+分叉
exec函數
分類:v[第二個參數是數組] l[第二個參數之后是變參] p[第一個參數是文件名] e[最后一個參數是環境變量]
字符串數組參數
execv()
execvp()
execve()
可變參數[printf()是典型的可變參]
execle()
execlp()
execl()
返回值
-1:失敗
不返回:成功
特點
一次調用,失敗返回
改朝換代,取而代之
PID不變
地址空間內容變化
本質
覆蓋程序
int system(Shell字符串)
返回值
-1:失敗
127:無法啟動shell來運行
其他:命令退出碼
特點
一次調用,一次返回
本質
shell執行命令/程序
###如何結束進程
進程的結束與生命結束相似。
return和exit()屬于壽終正寢,并且了結后事。
_exit()也屬于自殺,但是沒有料理后事。
abort()屬于意外死亡(車禍、病死),也沒有料理后事。
信號終止就是他殺。
main()函數return 0與exit(0)區別:
main()函數return 0 是語言級別的退出,退出后自動調用exit(0)
exit(0)是函數級別的退出。
exit(0)與abort()區別
exit(0)釋放所有的靜態的全局的對象,緩存,關掉所有的I/O通道,然后終止程序。
abort()直接終止程序,不釋放資源。
exit(0)與_exit()區別
exit()函數在調用_exit()系統調用之前要檢查文件的打開情況,把文件緩沖區中的內容寫回文件,清理I/O緩沖。
exit(0)是標準C函數。
_exit()不做清理I/O緩沖處理。_exit()是Linux系統調用。
main函數退出
return返回
只能在main函數內
調用exit()函數
一般用在main函數以外的函數
調用_exit()函數
一般用來結束子進程
調用abort()函數
一般用來異常退出
信號終止
終止其他進程
###如何停止進程
休眠 int sleep(unsigned int secs)
secs:指定休眠的秒數[-1:永久休眠]
返回值:未休眠的秒數
特性:如果沒有信號中斷,休眠指定秒數返回0,否則馬上返回休眠的秒數
暫停 int pause()
返回值:總是-1
特性
等待信號
Ctrl+C SIGINT 中斷
Ctrl+Z SIGTSTP 終端的停止信號
如果程序沒有處理信號,直接中斷,執行默認信號處理,程序后續代碼不再執行。
如果程序存在信號處理,執行信號處理后,執行后續代碼。
等待
pid_t wait(int* status) 等價pid_t waitpid(-1,status,0)
pid_t waitpid(pid_t pid,int* status,int options)
pid 等待的進程
<-1:等待進程組為pid的所有進程
-1:等待任何子進程
0:等待同組的進程
>0:進程為pid的子進程
status 子進程結束狀態
正常結束
WIFEXITED(status)
非0:正常結束子進程
0:非正常結束子進程
WEXITSTATUS(status)
取得子進程exit()返回的結束代碼
一般會先用WIFEXITED來判斷是否正常結束才能使用此宏
異常結束
WIFSIGNALED(status)
非0:異常結束子進程
0:非異常結束子進程
WTERMSIG(status)
取得子進程因信號而中止的信號代碼
一般會先用WIFSIGNALED來判斷后才使用此宏
暫停
WIFSTOPPED(status)
非0:暫停結束子進程
0:非暫停結束子進程
WSTOPSIG(status)
取得引發子進程暫停的信號代碼
一般會先用WIFSTOPPED來判斷后才使用此宏
option 選項
WNOHANG:若子進程沒有結束,返回0,不予以等待,若子進程結束,返回該子進程的ID
WUNTRACED:若子進程進入暫停狀態,則馬上返回,但子進程的結束狀態不予理會。
返回值
其他:等待PID
-1:失敗
其他
孤兒進程
父進程先于子進程退出
init進程作為新的父進程
無害
僵尸進程
子進程退出,父進程沒有獲得子進程的狀態信息[調用wait或waitpid]
避免出現僵尸進程
進程實例:簡易shell