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;
}
至此,进程的状态基本分析完毕