文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言控制进程之进程等待详解

2024-04-02 19:55

关注

进程等待的必要

当一个进程终止的时候,它的资源,比如说PCB,数据等不会被立马清理掉。它会保持在已经终止的状态,这种状态称为“僵尸状态”,直到被父进程确认。父进程wait,即父进程向内核确认子进程已经终止,可以为子进程“收尸”了,内核会把子进程的退出信息传给父进程,然后清理掉子进程的资源,这个时候子进程才算真正地终止了!

总结:

进程等待的方法

wait函数

一个进程可以通过调用wait函数等待子进程。wait函数是系统调用函数。

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

返回值:返回被等待进程的pid,如果等待失败,返回-1。

参数:输出型参数,可以获取子进程的退出状态,如果不需要获取子进程的退出状态,则设置为NULL。

测试:

 #include <stdio.h>                                                     
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <stdlib.h>
 int main(void)
 {
   pid_t id = fork(); //创建子进程
   if(id == 0)
   {
     //child
     //执行5秒
     int cnt = 5;
     while(cnt)
     {
       printf("child[%d] , cnt:%d\n", getpid(), cnt);
       sleep(1);
       cnt--;
     }
     exit(EXIT_SUCCESS);
   }
   sleep(10);
   pid_t ret = wait(NULL);
   if(ret > 0)
   {
     //wait success, ret is pid;
     printf("father wait child[%d] success\n", ret);
   }
   else{                                                                
     //wait failed.
     printf("father wait failed\n");
   }
   return 0;
 }

现象:子进程执行5秒后,终止了,但是内核没有立马清理掉它的资源,所以此时是僵尸状态,再过了5秒之后,父进程休眠完毕,然后等待子进程,确认子进程已经终止,返回子进程的pid,然后内核开始清理子进程资源,子进程真正地终止了,又过了5秒后父进程也终止了。

通过wait函数的输出型参数可以获得子进程的退出信息。

waitpid函数

waitpid函数也可以使得父进程等待子进程

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

先不关心第二个和第三个参数,第二个参数可以设置为NULL,第三个参数暂时设置为0。

第一个参数:

1、如果第一个参数pid传的是某个具体的进程的进程ID,表示等待该指定进程

2、如果第一个参数pid传的是-1,表示等待父进程的任意子进程。

第三个参数:

wait(&status) 等价于 waitpid(-1, &status, 0)

【注意事项】

获取子进程退出信息

在上述并没有具体解释参数status的作用。

status是一个指向整形的指针。但是一个进程的退出信息那么多,怎么可能会那么简单地用一个整型就知道进程的退出信息了呢?实际上,并不是简单地看待status指向的整形,而是当作位图来看,一个整型有32位,这样就可以全面地描述被等待进程的退出信息了。

只用研究低16个比特位。

进程退出的情况有四种:

1、正常退出(自愿,代码执行完,结果正确)

2、错误退出(自愿,代码执行完,结果不正确)

3、异常退出(非自愿,代码未执行完,退出码无意义)

4、被其他进程终止(非自愿,代码未执行完,退出码无意义)

这四种情况,可以按照进程是否收到信号来分类,第一种和第二种进程未收到信号,第三和第四种进程收到信号。

当被等待进程不是被信号所终止时,低8位全是0,而次低8位则是被等待进程的退出码。

当被等待进程是被信号所终止时,低7位表示被等待进程收到的信号。

如果进程是正常终止,如何显示地知道退出码?

如果进程是收到信号而终止,如何知道它收到了什么信号?直接就是低7位表示的是进程收到的信号,如果是非法的信号,说明它没有收到信号,这个值是无效的。

测试:

 #include <stdio.h>                                                    
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <stdlib.h>
 
 int main(void)
 {
   pid_t id = fork(); //创建子进程
   if(id == 0)
   {
     //child
     //执行5秒
     int cnt =7;
     while(cnt)
     {
       printf("child[%d] , cnt:%d\n", getpid(), cnt);
       sleep(1);
       cnt--;
     }
     exit(12);
   }
   sleep(10);
   int status;
   pid_t ret = waitpid(id, &status, 0);
   if(ret > 0)
   {
     //wait success, ret is pid;
     printf("father wait child[%d] success\n", ret);
   }
   else{
     //wait failed.
   printf("father wait failed\n");
   }
   printf("get a exit num : %d\n, get a single:%d", (status >> 8) & 0XF    FFF, status & 0XFFFF);
   sleep(2);                                                           
   return 0;
 }

当然,还可以不需要进行位运算,系统提供了两个宏,可以得到退出信息

 #include <stdio.h>                                                                                                                                              
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <stdlib.h>
 int main(void)
 {
   pid_t id = fork(); //创建子进程
   if(id == 0)
   {
     //child
    //执行5秒
    printf("i am child precess\n");
    sleep(5);
    exit(12);
  }
  sleep(3);
  int status;
  printf("father begin wait\n");
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0)
 {
    //wait success, ret is pid;
    printf("father wait child[%d] success\n", ret);
  }
  else{
    //wait failed.
    printf("father wait failed\n");
  }
  if(WIFEXITED(status))
  {
    printf("exit code : %d\n", WEXITSTATUS(status));
  }
  else{
    printf("get a signal\n");
 }
  sleep(2);
  return 0;
}   

执行结果

到此这篇关于C语言控制进程之进程等待详解的文章就介绍到这了,更多相关C语言进程等待内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯