进程——wait与waitpid、僵尸进程与孤儿进程
僵尸进程:子进程终止了,但是父进程没有回收子进程的资源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时可能会出现一下的情况:
- 阻塞(如果它的所有子进程都还在运行)。
- 带子进程的终止信息立即返回(如果一个子进程已终止,正等待父进程读取其终止信息)。
- 出错立即返回(如果它没有任何子进程)。
上图看到了,wai成功的返回值
*******************************************************************************************
对于wait和waitpid两个函数,有所不同的是:
- 如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0。
- 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、僵尸进程与孤儿进程的更多相关文章
- wait、waitpid 僵尸进程 孤儿进程
man wait: NAME wait, waitpid, waitid - wait for process to change state SYNOPSIS #include <sys/ty ...
- Linux-进程描述(3)之进程状态僵尸进程与孤儿进程
进程状态 进程状态反映进程执行过程的变化.这些状态随着进程的执行和外界条件的变化而转换.为了弄明正正在运行的进程是什么意思,我们需要知道进程的不同状态.一个进程可以有多个状态(在Linux内核中,进程 ...
- [linux]孤儿进程与僵尸进程
转载自:http://www.cnblogs.com/Anker/p/3271773.html 一.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两 ...
- PHP7 网络编程(三)孤儿进程与僵尸进程
基本概念 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 当一个 ...
- 多进程wait、僵尸进程、孤儿进程、prctl
1.概念 1.孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,从而保证每个进程都会有一个父进程.而Init进程会自 ...
- 【Linux 进程】孤儿进程、僵尸进程和守护进程
1.孤儿进程: 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作.孤儿进程是 ...
- OS之进程管理---孤儿进程和僵尸进程
僵尸进程 当一个进程终止时,操作系统会释放其资源,不过它位于进程表中的条目还是在的,直到它的父进程调用wait():这是因为进程表中包含了进程的退出状态.当进程已经终止,但是其父进尚未调用wait() ...
- 什么是PHP7中的孤儿进程与僵尸进程
什么是PHP7中的孤儿进程与僵尸进程 基本概念 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法 ...
- day34——僵尸进程和孤儿进程、互斥锁、进程之间的通信
day34 僵尸进程和孤儿进程 基于unix环境(linux,macOS) 主进程需要等待子进程结束之后,主进程才结束 主进程时刻监测子进程的运行状态,当子进程结束之后,一段时间之内,将子进程进行回收 ...
- day34 并行并发、进程开启、僵尸及孤儿进程
day34 并行并发.进程开启.僵尸及孤儿进程 1.并行与并发 什么是并行? 并行指的是多个进程同时被执行,是真正意义上的同时 什么是并发? 并发指的是多个程序看上去被同时执行,这是因为cpu在多个程 ...
随机推荐
- (简单) UVA 11624 Fire! ,BFS。
Description Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the ow ...
- Arduino中hex文件的保存及应用(转)
源:Arduino中hex文件的保存及应用 arduino在编译.链接.下载之后,hex文件自动删除了,造成软件仿真(如用proteus仿真)及其他单片机板应用的不便.以下是自己实践的小结,与大家分享 ...
- precision、recall、accuracy的概念
机器学习中涉及到几个关于错误的概念: precision:(精确度) precision = TP/(TP+FP) recall:(召回率) recall = TP/(TP+FN) accuracy: ...
- DateTime.CompareTo方法
DateTime.CompareTo(value)方法,与一个时间比较,返回整数,含义如下: 值 说明 小于零 此实例早于 value. 零 此实例与 value 相同. 大于零 此实例晚于 valu ...
- iOS开发——绘图电池按百分比显示
1.在DrawLine.h文件中提供了一个改变电池电量数值的接口 // // DrawLine.h // Demo-draw2 // // Created by yyt on 16/5/11. ...
- (中等) HDU 3265 Posters , 扫描线。
Problem Description Ted has a new house with a huge window. In this big summer, Ted decides to decor ...
- MapReduce 矩阵相乘
对于矩阵A[mn]*B[nl]=C[ml].这里可以并行起来的就是每个Cij,对于Cij而言,他是由A的第i行和B的第j列相乘得到.由于大的矩阵中经常是稀疏矩阵,所以一般用行列值表示 例如对于A: 1 ...
- JQuery中 json 和字符串直接相互转换
json字符串转json对象:jQuery.parseJSON(jsonStr); json对象转json字符串:JSON.stringify(jsonObj); IE中可能对unicode使用“ ...
- Python 线程池的实现
import urllib2 import time import socket from datetime import datetime from thread_pool import * def ...
- webstorm常用快捷键及插件
子曰:工欲善其事,必先利其器.那么问题来了,前端开发用什么比较好? 我反正用的是webstorm,之前也花了一些时间看看别人的使用方式.下面分类介绍一下. 常用快捷键: double shift : ...