wait( )和 waitpid( )

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。

#include <sys/types.h> 
#include <sys/wait.h>pid_t wait(int *status) 

参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL
如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。
下面是范例:

int main()
{pid_t pid = fork();switch (pid){case -1:perror ("fork");break;case 0:                 // 子进程printf ("我是子进程,我的ID是%d\n", getpid());sleep (3);exit (0);default:                // 父进程printf ("等待子进程挂掉\n");sleep (3);pid_t childId = wait (NULL);printf ("成功处理一个子进程,该子进程是:%d\n", childId);sleep (3);break;}return 0;
}

运行后发现,3秒钟的等待时间,这就是我们设定的让子进程睡眠的时间,只有子进程从睡眠中苏醒过来,它才能正常退出,也就才能被父进程捕捉到。其实这里我们不管设定子进程睡眠的时间有多长,父进程都会一直等待下去。

数status:如果参数status的值不是NULL,wait就会把子进程退出时的状态取出并存入其中,这是一个整数值(int),指出了子进程是正常退出还是被非正常结束的(一个进程也可以被其他进程用信号结束,我们将在以后的文章中介绍),以及正常结束时的返回值,或被哪一个信号结束的等信息。由于这些信息被存放在一个整数的不同二进制位中,所以用常规的方法读取会非常麻烦,人们就设计了一套专门的宏(macro)来完成这项工作,下面我们来学习一下其中最常用的两个:

1,WIFEXITED(status)这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。

(请注意,虽然名字一样,这里的参数status并不同于wait唯一的参数–指向整数的指针status,而是那个指针所指向的整数,切记不要搞混了。)

2, WEXITSTATUS(status)当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说,WIFEXITED返回0,这个值就毫无意义。
实例:

// status保存了被收集进程退出时的一些状态
int main()
{pid_t pid = fork();switch (pid){case -1:perror ("fork");break;case 0:                 // 子进程printf ("我是子进程,我的ID是%d\n",getpid());while (1);exit (0);default:                // 父进程printf ("等待子进程挂掉\n");int status;pid_t childId = wait (&status);printf ("成功处理一个子进程,该子进程是:%d %d\n", childId, status);if (WIFEXITED(status)){printf ("正常死亡\n");}else{printf ("被人做掉\n");}break;}return 0;
}

利用kill 杀死子进程。
这里写图片描述

这里写图片描述

wait一次只能处理一个僵尸进程:

// wait一次只能处理一个僵尸进程
int main()
{int count = 10;while (count--){pid_t pid = fork();switch (pid){case -1:perror ("fork");break;case 0:             // 子进程printf ("我是子进程,我的ID是%d\n", getpid());sleep (3);exit (0);default:            // 父进程break;}}printf ("等待子进程挂掉\n");while (1){pid_t childId = wait(NULL);if (-1 == childId){break;}printf ("成功处理一个子进程,该子进程是:%d\n", childId);}return 0;
}

这里写图片描述


#include <sys/types.h> 
#include <sys/wait.h>pid_t waitpid(pid_t pid,int *status,int options)

从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。下面我们就来详细介绍一下这两个参数:

pid
从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。

pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

options
options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用”|”运算符把它们连接起来使用
WNOHANG: 如果没有任何已经结束的子进程则马上返回,不予以等待。
WUNTRACED :如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。

返回值:如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。

int main()
{pid_t pid = fork();switch (pid){case -1:perror ("fork");break;case 0:                     // 子进程printf ("我是子进程,我的ID是%d\n", getpid());while (1);exit (0);default:                    // 父进程printf ("等待子进程挂掉\n");int status;pid_t childId = waitpid (-1, NULL, WNOHANG);printf ("成功处理一个子进程,该子进程是:%d, %d\n", childId, status);break;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

享受阅读的十二个好习惯

严谨的国际阅读率比较研究显示&#xff0c;当下韩国国民人均阅读量约为每年11本&#xff0c;法国约为8.4本&#xff0c;日本在8.4—8.5本之间。全世界每年阅读书籍数量排名第一的是犹太人&#xff0c;平均每人一年读书64本。而中国13亿人口&#xff0c;扣除教科书&#xff0c;平…

在 vscode 中使用 Git :拉取、提交、克隆

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 PS&#xff1a;转载此文后&#xff0c;网友在评论中提到还有其它方法&#xff0c;不过目前个人尚在研究中&#xff0c;有兴趣的朋友们也可…

偶也要去上海Tech一把了

公司组织的&#xff0c;后天去&#xff0c;呵呵&#xff1a;&#xff09;希望能多认识一点博客园的兄弟姐妹转载于:https://www.cnblogs.com/martinxj/archive/2004/09/14/42930.html

进程控制常用的一些操作

1、获取进程的id int main0() {printf ("当前进程 ID %d\n", getpid());printf ("当前父进程&#xff1a;%d\n", getppid());printf ("当前用户&#xff1a; %d\n", getuid());while (1);return 0; }2、fork 和 vfork之前的博客里有&#xf…

vscode 配置 git (配置、暂存、推送、拉取、免密)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 vscode 中对 git 进行了集成&#xff0c;很多操作只需点击就能操作&#xff0c;无需写一些 git 指令。 不过这就需要你对 vscode 进行配…

男女之间应该保留多少隐私

究竟&#xff0c;男女朋友之间&#xff0c;应该保留多少个人隐私? 我觉得&#xff0c;如果各自的隐私太多,那么&#xff0c;很难会相信彼此的爱能有多深浓。然而&#xff0c;如果两个人没有半点隐私,而且绝对坦诚。 彼此的行为和思想也没有丝毫隐瞒的话,这种清白赤诚有如标…

处理bugs心法

1. 前提 第一层&#xff1a;遇到异常首先必须告诉自己&#xff0c;冷静&#xff0c;不要慌。&#xff08;一看到Bug就心慌&#xff0c;那么武功就施展不了了&#xff09; 2. 入门级 第二层&#xff1a;遇到Bug&#xff0c;第一潜意识看输出异常的信息的&#xff08;控制台输出&…

C语言实现简单的电子通讯录2

这两天学完系统调用和标准IO&#xff0c;之前的通讯录可以进行一些改进&#xff0c;将数据保存到文件中(图我这里就不发了)。 原理&#xff1a;每次启动程序时先从预设文件中以只读的形式读取保存的通讯录信息&#xff0c;然后将读取到的信息导入到结构体中&#xff1b;每次执…

解决 VS Code 保存时候自动格式化

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 不知道从哪个版本起&#xff0c;VS code 保存会自动格式化。 以前都是altshiftF格式化的&#xff0c;现在一保存就格式化&#xff0c;而…

发布在线文档【软件=业务+架构+流程+组织.pptx】

10年的技术工作&#xff0c;软件这个词对我来说一点都不陌生&#xff0c;但是当我问自己如何理解软件的&#xff1f;我却不知道如何回答。软件&#xff1d;业务&#xff0b;架构&#xff0b;流程&#xff0b;组织&#xff0c;其中公式是借用软件产品线工程BAPO的概念&#xff0…

12种食物最养男人 10种食物最养女人 太值得收藏了

据统计&#xff0c;男性10大死因中有4项与饮食有关&#xff0c;包括癌症、脑血管疾病、心脏病和糖尿病。以下12种食品对男性健康有益&#xff0c;建议男性多多摄取。 男人需要的十种养生食物 No.1西红柿 西红柿的酸味能促进胃液分泌&#xff0c;帮助消化蛋白质等&#xff…

ES 基础

1. ES 基础一网打尽 1.1 ES定义 ESelaticsearch简写&#xff0c; Elasticsearch是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数据。 Elasticsear…

为什么 那么多 前端开发者都想学 Vue.js

根据JavaScript 2017 前端库状况调查 Vue.js是开发者最想学的前端库。我在这里说明一下我为什么认为这也是和你一起通过使用 Vue 构建一个简单的 App 应用程序的原因。 我最近曾与 Evan You&#xff0c;Chris Fritz&#xff0c;Sarah Drasner&#xff0c;和 Adam Jahr 做了一个…

进程间通信之管道通信

两个程序之间传递数据的一种简单方法是使用popen和pclose。 #include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream); popen函数允许一个程序将另一个程序作为新进程来启动&#xff0c;并可以传递数据给它或者通过它接收数据…

vue 各组件 使用 Demo

环境搭建 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 假设你已经通读vue官方文档&#xff08;文档都没读一遍&#xff08;至少&#xff09;&#xff0c;那不建议动手撸码&#xff…

Dropbox推独立应用,公司估值已达100亿美元

摘要&#xff1a;Dropbox刚获得5亿美元的新一轮融资&#xff0c;其估值已高达100亿美元&#xff0c;现在又推出针对云服务的独立应用Carousel&#xff0c;不久之后&#xff0c;还会有应用陆续推出&#xff0c;随着美国前国务卿赖斯的加盟&#xff0c;Dropbox在云市场的表现异常…

SQL经典面试题(二)

有3个表S&#xff0c;C&#xff0c;SCS&#xff08;SNO&#xff0c;SNAME&#xff09;代表&#xff08;学号&#xff0c;姓名&#xff09; //主键&#xff1a;SNO //多个人&#xff0c;多门课 3张表 &#xff0c;SC 关系表C&#xff08;CNO&#xff0c;CNAME&#xff0c;…

进程间通信之信号he信号量

信号的篇幅较少&#xff0c;就把他和信号量放在一起了。先讲讲他们之间的区别&#xff1a; 1.信号&#xff1a;&#xff08;signal&#xff09;是一种处理异步事件的方式。信号时比较复杂的通信方式&#xff0c;用于通知接受进程有某种事件发生&#xff0c;除了用于进程外&…

开源当自强:我们不是“便宜货”

之前人们争相使用开源软件&#xff0c;无非是因为它便宜、好用、易得&#xff0c;不过根据最新的开源软件调查显示&#xff0c;人们使用开源软件最主要的原因还是看重它的高质量。 成本低是很过公司参与开源项目的最主要原因之一&#xff0c;而现在他们视开源是一条通往创新、省…

前端学习:Vue.js基本使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Vue教程文档&#xff1a; https://cn.vuejs.org/v2/guide/ 定义 实例&#xff1a; new Vue() 挂载点: el 数据&#xff1a;data 模…