Linux中wait()函数(1)

最全的Linux教程,Linux从入门到精通

======================

  1. linux从入门到精通(第2版)

  2. Linux系统移植

  3. Linux驱动开发入门与实战

  4. LINUX 系统移植 第2版

  5. Linux开源网络全栈详解 从DPDK到OpenFlow

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。

需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

23 {
24
25   int count = 0;
26
27   pid_t pid = fork();
28   int status = -1;
29  
30   if(pid<0)
31   {
32     printf(“fork error for %m\n”,errno );
33   }else if(pid>0)
34   {
35     printf(“this is parent ,pid = %d\n”,getpid() );
36     wait(&status);//父进程执行到此,马上阻塞自己,直到有子进程结束。当发现有子进程结束时,就会回收它的资源。
37    
38   }else
39   {
40     printf(“this is child , pid = %d , ppid = %d\n”,getpid(),getppid() );
41     int i;
42    
43     for (i = 0; i < 10; i++) {
44       count++;
45       sleep(1);
46      
47       printf(“count = %d\n”, count)  ;
48      
49     }
50
51     exit(5);
52    
53   }
54   printf(“child exit status is %d\n”, WEXITSTATUS(status));//status是按位存储的状态信息,需要调用相应的宏来还原一下
55  
56   printf(“end of program from pid = %d\n”,getpid() );
57  
58  
59 }


![复制代码](https://common.cnblogs.com/images/copycode.gif)


运行结果:


![](https://pic002.cnblogs.com/images/2012/347216/2012012703425870.png)


waitpid系统调用在Linux函数库中的原型是:


     #include <sys/types.h> /\* 提供类型pid\_t的定义 \*/


     #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取不同的值时,在这里有不同的意义。


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


**options:**


options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用,比如:


     ret = waitpid(-1,  NULL,  WNOHANG | WUNTRACED);


如果我们不想使用它们,也可以把options设为0,如:


     ret = waitpid(-1,  NULL,  0);


如果使用了WNOHANG参数调用waitpid,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去。


而WUNTRACED参数,由于涉及到一些跟踪调试方面的知识,加之极少用到,这里就不多费笔墨了,有兴趣的读者可以自行查阅相关材料。


***看到这里,聪明的读者可能已经看出端倪了:wait不就是经过包装的waitpid吗?没错,察看<内核源码目录>/include/unistd.h文件349-352行就会发现以下程序段:***


***static inline pid\_t wait(int \* wait\_stat)***


***{***


***return waitpid(-1,wait\_stat,0);***


***}***


***返回值和错误***


waitpid的返回值比wait稍微复杂一些,一共有3种情况:


          1、当正常返回的时候,waitpid返回收集到的子进程的进程ID;


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


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


当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD;



/* waitpid.c */

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

int main()

{

    pid_t pc, pr;

    pc=fork();

    if(pc<0) /* 如果fork出错 */
    {

       printf("Error occured on forking./n");
    }

    else if(pc==0) /* 如果是子进程 */
    {
       sleep(10); /* 睡眠10秒 */

       exit(0);
    }

    /* 如果是父进程 */

   do{

       pr=waitpid(pc, NULL, WNOHANG); /* 使用了WNOHANG参数,waitpid不会在这里等待 */

       if(pr==0) /* 如果没有收集到子进程 */
        {

          printf("No child exited/n");

          sleep(1);

        }

      }while(pr == 0); /* 没有收集到子进程,就回去继续尝试 */

    if(pr == pc)
      {
        printf("successfully get child %d/n", pr);
      }
    else

        printf("some error occured/n");

}


***编译并运行:***


*$ cc waitpid.c -o waitpid*


*$ ./waitpid*


*No child exited*


*No child exited*


*No child exited*


*No child exited*


*No child exited*


*No child exited*


*No child exited*


*No child exited*


*No child exited*


*No child exited*


*successfully get child 1526*


父进程经过10次失败的尝试之后,终于收集到了退出的子进程。


**先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里**

**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/5be3eb90261a9c25c1ac427e6bd0e56b.png)
![img](https://img-blog.csdnimg.cn/img_convert/fe58d9b68e8aa6e8f31670f122515765.png)
![img](https://img-blog.csdnimg.cn/img_convert/5c3aa61fa181c5f207829c8f48ed6c2f.png)
![img](https://img-blog.csdnimg.cn/img_convert/0e2ea25a4e67858b3ee88d18da554747.png)
![img](https://img-blog.csdnimg.cn/img_convert/d40b51f9048cd4af8af05593858bd925.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

246)]
[外链图片转存中...(img-C48F5E8c-1715786735246)]
[外链图片转存中...(img-9hTGxCrI-1715786735247)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值