task_struct內容分類
標識符:描述本進程的唯一標識符,用來區別其他進程
狀態:任務狀態,退出代碼,退出信號等
優先級:相對於其他進程的優先級
程序計數器:程序中即將被執行的下一條指令的地址
內存指針:包括程序代碼和進程相關數據的指針,還有和其他進程共享的內存塊的指針
上下文數據:進程執行時處理器的寄存器中的數據
I/O狀態信息:包括顯示的I/O請求,分配給進程的I/O設備和被進程使用的文件列表
記賬信息:可能包括處理器時間總和,使用的時鐘數總和,時間限制,記賬號等
其他信息
進程的組織:
可以在內核源代碼裏找到,所有運行在系統裏的進程都以task_struck鏈表的形式存在內核裏。
進程的狀態:
R運行狀態(running):並不意味進程一定在運行中,它表明進程要麼是在運行中要麼在運行隊列裏
S睡眠狀態(sleeping):意味着進程在等待事件完成(可中斷睡眠(interruptible sleep))
D磁盤休眠狀態(Disk sleep):有時也叫不可中斷睡眠(uninterrupted sleep),在這個狀態的進程通常會等待IO的結束
T停止狀態(stopped):可以通過發送sigstop信號給進程來停止(T)進程。這個被暫停的進程可以通過發送sigcont信號讓進程繼續運行
X死亡狀態(dead):這個狀態只是一個返回狀態,你不會在任務列表裏看到這個狀態
殭屍進程
僵死狀態(zombies)是一個比較特殊的狀態。當進程退出並且父進程沒有讀取到子進程退出的返回代碼時就會產生僵死(屍)進程,僵死進程會以終止狀態保持在進程表中,並且會一直在等待父進程讀取退出狀態碼,所以,只要子進程退出,父進程還在運行,但父進程沒有讀取子進程狀態,子進程進入Z狀態。如下即爲僵死進程示例:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
pid_t pid = fork();
if(pid < 0){
perror("fork");
return 1;
}else if(pid == 0){//child
printf("i am child[%d],now Z.....\n",getpid());
sleep(3);
exit(EXIT_SUCCESS);
}else {//father
printf("i am father[%d],now S.....\n",getpid());
sleep(10);
}
return 0;
}
殭屍進程的退出必須被維持,以爲父進程要知道子進程的結果,可要是父進程一直不讀取,那麼就一直處於Z狀態。
孤兒進程
孤兒進程,顧名思義,孤兒進程是父進程提前退出,子進程後退出進入僵死狀態,因爲回收他的父進程已經退出了,如果得不到回收,就會造成內存泄漏,所以,操作系統會對其進行回收處理。即1號進程init領養此孤兒進程並回收。如下例子:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
pid_t pid = fork();
if(pid < 0){
perror("fork");
return 1;
}else if(pid == 0){//child
printf("i am child[%d]\n",getpid());
sleep(10);
}else {
printf("i am father[%d]\n",getpid());
sleep(3);
exit(0);
}
return 0;
}
至此,進程的狀態基本分析完畢