Linux下进程状态
- Linux进程状态:R (TASK_RUNNING),可执行状态。
- Linux进程状态:S (TASK_INTERRUPTIBLE),可中断的睡眠状态.
- Linux进程状态:D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。
- Linux进程状态:T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。
- Linux进程状态:Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。
- Linux进程状态:X (TASK_DEAD -EXIT_DEAD),退出状态,进程即将被销毁。
状态演示
写一个小程序,一个while(1)死循环。在另一个终端下查看当前进程的状态。可以看到是R+表示正在执行状态。(+号表示在前台运行)
接下来用kill -19(SIGSTOP)信号暂停该进程。
可以看到此时该进程状态变成了T暂停状态。
再用kill -18(SIGCONT)信号恢复该进程。
僵尸进程
僵尸进程是指当进程退出,但父进程没有读取到子进程退出的返回代码时就会产生僵尸进程。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int ret=fork();
if(ret==0)
{
printf("child pid=%d\n",getpid());
sleep(10);
exit(0);
}
else if(ret>0)
{
printf("father pid=%d\n",getpid());
sleep(30);
}
return 0;
}
此时可以看到子进程变成了Z状态,子进程就变成了僵尸进程。
1.僵尸进程的退出状态必须需要维护,因为父进程需要知道子进程退出时的信息。因为一个进程退出有可能是执行完成并且结果正确,可能是执行完成但结果不正确,也可能是执行中途就异常退出了。所以父进程就有必要知道子进程的退出状态如何,简单来说,父进程需要知道他交给子进程做的事做的怎么样。如果父进程一直不读取,子进程就会一直是僵尸状态。
2.维护退出本身就是用数据去维护,也属于进程基本信息,就需要保存在task_struct中,PCB一直需要用数据来维护。
3.如果父进程创建很多子进程,但是不回收子进程,就会造成内存越来越少,就会产生内存泄漏。
孤儿进程
孤儿进程是指:父进程先退出,子进程就变成了孤儿进程。
孤儿进程会被操作系统的一号init进程领养,也由一号init回收。
#include <stdio.h>
int main()
{
int ret=fork();
if(ret==0)
{
printf("child pid=%d\n",getpid());
sleep(30);
}
else if(ret>0)
{
printf("father pid=%d\n",getpid());
sleep(5);
exit(0);
}
return 0;
}
可以看到子进程被一号进程收养。
来自百度百科一段生动的说明:孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。