Linux进程理解( 七 )


我们这里有点疑惑,为何要进入Z状态,感觉有点多此一举,反正这个进程肯定会被释放掉.我们先来解释一下为何一个进程会被创建出来.我们肯定是需要完成任务的,那么当进程结束后,我们是如何知道这个任务是不是被完成了,也就是说现在你还不能被释放掉,必须把情况给我说明白,之后才能被释放.
Z状态就是维护退出信息,把退出的信息告诉父进程或者OS,至于怎么做的我们先不谈.我记得Linux内核存咋退出信息.我们之前main函数的返回值也是放在这里面,这个到进程控制在细谈.
僵尸进程
处于Z状态的进程叫做僵尸进程,当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 我们看看能不能模拟出来.
#include #include #include int main(){pid_t id = fork();if(id == 0){int cout = 5;while(cout){printf("我是子进程  , 还存在%d s\n",cout--);sleep(1);}printf("我是一个僵尸进程 , 等待被回收\n");exit(0);}else{while(1){printf("我是父进程\n");sleep(1);}}return 0;}
我们这里有一个检测的指令,大家会用就可以了,让他一直检测这个进程的信息.
[bit@Qkj 08_11]$ while :; do ps xaj | head -1 && ps xaj | grep 'mybin' | grep -v gr;sleep 1;echo "####################################";done
现在我们开始看僵尸进程的状态,这里你就会发现子进程变成了一个Z状态的进程.
僵尸状态危害
长时间存在僵尸状态,父进程不会回收它,导致里面的资源不会被释放,这就构成了内存泄漏.至于后面如何回收,后面再谈.
孤儿进程
既然谈过僵尸进程了 , 这里也把孤儿进程说一下吧孤儿进程很是形象 , 就是父母找不到了 , 孩子在孤儿院 。对应进程也是如此 , 如果一个进程的父进程死掉了 , 那么这个子进程就变了孤儿进程.
#include#include #include int main(){pid_t id = fork();if(id == 0){while(1){printf("我是子进程\n");sleep(1);}}else {int cout = 10;while(cout){printf("我是父进程,还剩 %d s\n",cout--);sleep(1);}printf("父进程已经 死亡\n");}return 0;}
这里你会发现我们的子进程变成了一个孤儿进程,它的父进程没有了,所以被1号进程给收养了,所谓的1好进程就是操作系统.那么操作系统为何要收养这个孤儿进程,就是为了以后这个孤儿进程死掉后释放资源.
我们发现父进程好象是直接退出的了,没有经过Z状态 , 这是为什么呢?父进程是bash的子进程,当父进程退出后,bash是存在可以释放父进程资源的方法,就把它直接释放了,故我们看到的是越过了Z状态.
这里我们还会看到一个情况,这个孤儿进程的状态是S,我们这个不担心,但是你往上面翻,上面的所有进程状态后面都带了一个+号,这个存在些区别.
后台进程
状态后面不带+号的是后台进程,这个进程是不能够被ctrl+c杀掉的,这里需要使用kill指令.算是补充上面的一个坑.同样后面带+号的是前台进程,可以被我们杀掉.
T 状态 & t 状态
还剩下,两个状态,某种意义上它们两个算同一个进程状态,再新的Linux内核中好象都是T.这里我们只是简单的认识一下它们两个.
T 状态
T状态时是暂停状态,我们在日常生活中碰见过暂停,比如说听一首歌,突然有些事,这里可以暂停一下.进程也是如此.
我们先来看看kill\指令的选项,这里不要求记忆,但是需要理解.
[bit@Qkj 08_12]$ kill -l