当前位置:   article > 正文

【Linux】僵尸与孤儿 && 进程等待_linux 僵尸进程

linux 僵尸进程

目录

一,僵尸进程

1,僵尸进程

2,僵尸进程的危害

二,孤儿进程

1,孤儿进程

三,进程等待

1,进程等待的必要性

2,wait 方法

3,waitpid 方法

4,回收小结


一,僵尸进程

1,僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。

当进程退出并且父进程(使用wait()系统调用,后面讲) 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

来一个创建维持30秒的僵死进程例子:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. pid_t id = fork();
  6. if (id < 0) {
  7. perror("fork");
  8. return 1;
  9. }
  10. else if (id > 0) { //parent
  11. printf("parent[%d] is sleeping...\n", getpid());
  12. sleep(30);
  13. }
  14. else {
  15. printf("child[%d] is begin Z...\n", getpid());
  16. sleep(5);
  17. exit(EXIT_SUCCESS);
  18. }
  19. return 0;
  20. }

当fork()函数返回值,父进程和子进程同时启动,当子进程运行结束退出进程时,父进程还在等待,此时子进程一直在等待父进程读取其退出状态代码,于是产生了僵尸状态;

僵尸状体会造成内存泄漏,我们要尽可能避免;

2,僵尸进程的危害

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!

维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护?是的!

那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

内存泄漏?是的!

二,孤儿进程

1,孤儿进程

父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?

父进程先退出,子进程就称之为“孤儿进程”

孤儿进程被1号init进程领养,当然要有init进程回收喽。

我们写一个进程来感受一下:

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. int main()
  5. {
  6. pid_t id = fork();
  7. if (id < 0) {
  8. perror("fork");
  9. return 1;
  10. }
  11. else if (id == 0) {//child
  12. printf("I am child, pid : %d\n", getpid());
  13. sleep(10);
  14. }
  15. else {//parent
  16. printf("I am parent, pid: %d\n", getpid());
  17. sleep(3);
  18. exit(0);
  19. }
  20. return 0;
  21. }

fork()函数返回后,子进程和父进程同时运行,当父进程执行结束并且退出后,子进程还在运行,此时子进程沦为孤儿!

一般孤儿进程最后会被1号init进程领养,不会造成内存泄漏;

三,进程等待

1,进程等待的必要性

之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。

另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。

最后,父进程派给子进程的任务完成的如何,我们需要知道。如子进程运行完成,结果对还是不对, 或者是否正常退出。

父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

2,wait 方法

pid_t wait(int*status);

返回值: 成功返回被等待进程pid,失败返回-1。

参数: 输出型参数,获取子进程退出状态,不关心则可以设置成为NULL

  1. #include <stdio. h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include<sys/types.h>
  5. #include<sys / wait.h>
  6. int main()
  7. {
  8. pid_t id = fork();
  9. if (id < 0) {
  10. perror("fork");
  11. return 1;
  12. }
  13. else if (id == 0) {
  14. //parent
  15. printf("child[%d] is sleeping...\n", getpid());
  16. sleep(5);
  17. exit(3);
  18. }
  19. int status = 0;
  20. pid_t rid = wait(&status);
  21. if (rid > 0)
  22. {
  23. printf("parent[%d] is begin Z...\n", rid);
  24. sleep(10);
  25. }
  26. else
  27. {
  28. printf("进程失败:rid:%d\n", rid);
  29. }
  30. return 0;
  31. }

这样子 wait 会自动及时回收子进程,不会形成僵尸,不会造成内存泄漏;

3,waitpid 方法

pid_ t waitpid(pid_t pid, int *status, int options);

返回值: 当正常返回的时候waitpid返回收集到的子进程的进程ID;

如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;

如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

参数:

pid: Pid=-1,等待任一个子进程。与wait等效。 Pid>0.等待其进程ID与pid相等的子进程。 status: WIFEXITED(status):

若为正常终止子进程返回的状态,则为真。

(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码) options: WNOHANG:

若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进 程的ID。

  1. #include <stdio. h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include<sys/types.h>
  5. #include<sys / wait.h>
  6. int main()
  7. {
  8. pid_t id = fork();
  9. if (id < 0) {
  10. perror("fork");
  11. return 1;
  12. }
  13. else if (id == 0) {
  14. //parent
  15. printf("child[%d] is sleeping...\n", getpid());
  16. sleep(5);
  17. exit(3);
  18. }
  19. int status = 0;
  20. pid_ t rid = waitpid(-1,&status,0);
  21. if (rid > 0)
  22. {
  23. printf("parent[%d] is begin Z...\n", rid);
  24. sleep(10);
  25. }
  26. else
  27. {
  28. printf("进程失败:rid:%d\n", rid);
  29. }
  30. return 0;
  31. }

4,回收小结

如果子进程已经退出,调用wait/waitpid时,wait/waitpid 会立即返回,并且释放资源,获得子进程退出信息。

如果在任意时刻调用 wait/waitpid,子进程存在且正常运行,则进程可能阻塞。

如果不存在该子进程,则立即出错返回。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/830721
推荐阅读
相关标签
  

闽ICP备14008679号