僵尸进程:子进程终止了,但是父进程没有回收子进程的资源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. linux 驱动入门3

    不吃苦中苦,难为人上人.努力,给老婆孩子提供个良好的生活居住环境. http://www.cnblogs.com/nan-jing/articles/5806399.html 上文提到.可以自动创建了 ...

  2. laravel5 数据库连接问题

    [PDOException] SQLSTATE[28000] [1045] Access denied for user ‘homestead’@’localhost’ (using password ...

  3. SVN简单流程---以公司的使用方法为例

    一  名词解释 svn一般包括      branch  每个branch版本都要生成对应的tag.例如 branch版本号为1.0.0,那么提交后生成的tag版本号为1.0.0.0;当branch修 ...

  4. DDR工作原理(转)

    源:DDR工作原理 DDR SDRAM全称为Double Data Rate SDRAM,中文名为“双倍数据流SDRAM”.DDR SDRAM在原有的SDRAM的基础上改进而来.也正因为如此,DDR能 ...

  5. X-008 FriendlyARM tiny4412 uboot移植之copy u-boot到DDR内存

    <<<<<<<<<<<<<<<<<<<<<<<<< ...

  6. 关于中值滤波算法,以及C语言实现(转)

    源:关于中值滤波算法,以及C语言实现 1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制 ...

  7. .NET防止重复提交数据

    最近在做一个销售系统的时候,操作人员提交数据的时候数据库竟然会出现多条数据相同的记录,并且是在1秒之内,客户反馈给我们,第一反应是重复提交的问题,检查了下代码,程序执行完成后应该是跳转到别的页面的,可 ...

  8. MyEclipse 显示行标

    方法一:在行的显示行标位置(行前),右键->Show Line numbers 方法二:Window->preferences->General->editor->tex ...

  9. 让表格table呈现边框,不用给tr、td加边框的写法

    <table width="100%" cellspacing="1" cellpadding="1" bgcolor="# ...

  10. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)&&莫对算法

    这里跟曼哈顿最小生成树没有太大的关系. 时间复杂度证明: [BZOJ2038 小Z的袜子 AC代码] 排序方式: 第一关键字:l所在的块: 第二关键字:r从小到大. #include<cstdi ...