僵尸进程:子进程终止了,但是父进程没有回收子进程的资源PCB。使其成为僵尸进程

孤儿进程:父进程先与子进程结束了,使得子进程失去了父进程,这个时候子进程会被1号进程init进程领养,成为孤儿进程

为了防止上面两种情况,我们应当在父进程结束之前一定要回收子进程的所有资源

所以出现了wait和waitpid

#include <sys/types.h>
#include <sys/wait.h> pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options); status是一个传出参数。
waitpid的pid参数选择:
< - 回收指定进程组内的任意子进程
= - 回收任意子进程
= 回收和当前调用waitpid一个组的所有子进程
> 回收指定ID的子进程

一个进程结束的时候,会关闭所有的文件描述符,释放所有的内存空间,但是他的PCB仍然存在,保存着子进程的一些状态信息,如果进程正常退出,保存着正常退出的状态,如果非正常退出,那么保存着是哪个信号导致的该进程退出,父进程可以通过wait和waitpid查看到这些信息,并且彻底清除,我们知道shell是所有进程的父进程,在shell中可以通过 $查看退出状态编号,所以可以通过shell查看并清除,如果一个进程退出,父进程并没有调用wait和waitpid进程清除,那么就产生了僵尸进程,正常情况下,僵尸进程都被父进程清理了

下面写一个不正常了程序,使得父进程不结束

#include <unistd.h>
#include <stdlib.h> int main(void)
{
pid_t pid=fork(); if(pid<) {
perror("fork");
exit();
} if(pid>) { /* parent */
while();
} /* child */
return ;
}

上面中,父进程一直处于while(1)循环,使得父进程不退出,下图查看ps aux可以发现父进程状态为R,子进程状态为Z(僵尸态Zombie)

 对于wait或waitpid函数若调用成功则返回清理掉的子进程id,若调用出错则返回-1。父进程调用wait或waitpid时可能会出现一下的情况:

  1. 阻塞(如果它的所有子进程都还在运行)。
  2. 带子进程的终止信息立即返回(如果一个子进程已终止,正等待父进程读取其终止信息)。
  3. 出错立即返回(如果它没有任何子进程)。

上图看到了,wai成功的返回值

*******************************************************************************************

  对于wait和waitpid两个函数,有所不同的是:

  1. 如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0。
  2. wait等待第一个终止的子进程,而waitpid可以通过pid参数指定等待哪一个子进程。

所以,调用wait和waitpid不仅可以获得子进程的终止信息,还可以使父进程阻塞等待子进程终止,起到进程间同步的作用。如果参数status不是空指针,则子进程的终止信息通过这个参数传出,如果只是为了同步而不关心子进程的终止信息,可以将status参数指定为NULL。

 #include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h> int main(void)
{
pid_t pid,pid_c; int n = ;
pid = fork(); if(pid > )
{/* in parent */
while()
{
printf("I am parent %d\n",getpid());
//wait是一个阻塞函数,等待回收子进程资源,如果没有子进程,wait返回-1
pid_c = wait(NULL);
printf("wait for child %d\n",pid_c);
sleep();
}
}
else if(pid == )
{/* in child */
printf("I am child %d\n",getpid());
sleep();
} return ;
} 运行结果:
I am parent
I am child
wait for child
I am parent
wait for child -
I am parent
wait for child -
I am parent

孤儿进程

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> int main(void)
{
pid_t pid;
int n=;
pid = fork();
if(pid > )
{//创建完之后父进程就退出了
printf("I am parent\n");
exit();
}
else if(pid == )
{//此时父进程退出,子进程被init程序接管,该进程的父进程号变成1
while(n--)
{
printf("I am %d, my parent is %d\n",getpid(),getppid());
sleep();
}
}
else
{
perror("fork");
exit(-);
}
return ;
} 运行结果:
I am , my parent is
I am , my parent is
I am , my parent is
I am , my parent is
I am , my parent is
I am , my parent is

waitpad

 #include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h> int main(void)
{
pid_t pid;
pid = fork();
if (pid < )
{
perror("fork failed");
exit();
} if (pid == )
{//in child
int i;
for (i = ; i > ; i--) {
printf("This is the child %d\n",getpid());
sleep();
}
exit();//返回3,运行时可以看到
//子进程睡眠3秒之后就退出了
} else
{//in parent
int stat_val;
waitpid(pid, &stat_val, );//以阻塞方式等待回收子进程,第三个参数0,表示阻塞方式
if (WIFEXITED(stat_val))//正常退出
printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
else if (WIFSIGNALED(stat_val))//查看被什么信号关闭
printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val));
}
return ;
}

进程——wait与waitpid、僵尸进程与孤儿进程的更多相关文章

  1. wait、waitpid 僵尸进程 孤儿进程

    man wait: NAME wait, waitpid, waitid - wait for process to change state SYNOPSIS #include <sys/ty ...

  2. Linux-进程描述(3)之进程状态僵尸进程与孤儿进程

    进程状态 进程状态反映进程执行过程的变化.这些状态随着进程的执行和外界条件的变化而转换.为了弄明正正在运行的进程是什么意思,我们需要知道进程的不同状态.一个进程可以有多个状态(在Linux内核中,进程 ...

  3. [linux]孤儿进程与僵尸进程

    转载自:http://www.cnblogs.com/Anker/p/3271773.html 一.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两 ...

  4. PHP7 网络编程(三)孤儿进程与僵尸进程

    基本概念 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 当一个 ...

  5. 多进程wait、僵尸进程、孤儿进程、prctl

    1.概念 1.孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,从而保证每个进程都会有一个父进程.而Init进程会自 ...

  6. 【Linux 进程】孤儿进程、僵尸进程和守护进程

    1.孤儿进程: 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作.孤儿进程是 ...

  7. OS之进程管理---孤儿进程和僵尸进程

    僵尸进程 当一个进程终止时,操作系统会释放其资源,不过它位于进程表中的条目还是在的,直到它的父进程调用wait():这是因为进程表中包含了进程的退出状态.当进程已经终止,但是其父进尚未调用wait() ...

  8. 什么是PHP7中的孤儿进程与僵尸进程

    什么是PHP7中的孤儿进程与僵尸进程 基本概念 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法 ...

  9. day34——僵尸进程和孤儿进程、互斥锁、进程之间的通信

    day34 僵尸进程和孤儿进程 基于unix环境(linux,macOS) 主进程需要等待子进程结束之后,主进程才结束 主进程时刻监测子进程的运行状态,当子进程结束之后,一段时间之内,将子进程进行回收 ...

  10. day34 并行并发、进程开启、僵尸及孤儿进程

    day34 并行并发.进程开启.僵尸及孤儿进程 1.并行与并发 什么是并行? 并行指的是多个进程同时被执行,是真正意义上的同时 什么是并发? 并发指的是多个程序看上去被同时执行,这是因为cpu在多个程 ...

随机推荐

  1. (简单) UVA 11624 Fire! ,BFS。

    Description Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the ow ...

  2. Arduino中hex文件的保存及应用(转)

    源:Arduino中hex文件的保存及应用 arduino在编译.链接.下载之后,hex文件自动删除了,造成软件仿真(如用proteus仿真)及其他单片机板应用的不便.以下是自己实践的小结,与大家分享 ...

  3. precision、recall、accuracy的概念

    机器学习中涉及到几个关于错误的概念: precision:(精确度) precision = TP/(TP+FP) recall:(召回率) recall = TP/(TP+FN) accuracy: ...

  4. DateTime.CompareTo方法

    DateTime.CompareTo(value)方法,与一个时间比较,返回整数,含义如下: 值 说明 小于零 此实例早于 value. 零 此实例与 value 相同. 大于零 此实例晚于 valu ...

  5. iOS开发——绘图电池按百分比显示

    1.在DrawLine.h文件中提供了一个改变电池电量数值的接口 // //  DrawLine.h //  Demo-draw2 // //  Created by yyt on 16/5/11. ...

  6. (中等) HDU 3265 Posters , 扫描线。

    Problem Description Ted has a new house with a huge window. In this big summer, Ted decides to decor ...

  7. MapReduce 矩阵相乘

    对于矩阵A[mn]*B[nl]=C[ml].这里可以并行起来的就是每个Cij,对于Cij而言,他是由A的第i行和B的第j列相乘得到.由于大的矩阵中经常是稀疏矩阵,所以一般用行列值表示 例如对于A: 1 ...

  8. JQuery中 json 和字符串直接相互转换

    json字符串转json对象:jQuery.parseJSON(jsonStr); json对象转json字符串:JSON.stringify(jsonObj);   IE中可能对unicode使用“ ...

  9. Python 线程池的实现

    import urllib2 import time import socket from datetime import datetime from thread_pool import * def ...

  10. webstorm常用快捷键及插件

    子曰:工欲善其事,必先利其器.那么问题来了,前端开发用什么比较好? 我反正用的是webstorm,之前也花了一些时间看看别人的使用方式.下面分类介绍一下. 常用快捷键: double shift : ...