【进程等待】是什么 | 为什么 | 怎么办 | wait阻塞等待

news2025/1/11 23:41:17

目录

进程等待是什么?

为什么要进程等待? 

如何进程等待?

wait 

阻塞等待 


进程等待是什么?

  • 进程终止会把进程退出的数据(退出码和退出信号)存放到进程的PCB中保存下来,让父进程进行等待。
  • 任何一个子进程在退出时,默认情况下,必须被父进程等待。
  • 任何子进程,在退出的情况下马,一般必须要被父进程进行等待。
  • 3号手册是库函数
  • 2号手册是系统调用函数

  • 若这个子进程的父进程被杀死或父进程不存在,则这个子进程被称为孤儿进程。
  • 孤儿进程会被OS领养,所以严格来讲父进程也存在,父进程就是OS。

  • 子进程在退出的时候,如果父进程不管不顾(父进程不等待)。

  • 子进程退出之后,就处于Z状态(僵尸状态),一直处于Z状态。

  • 很多进程处于Z状态且一直处于Z状态,进程的PCB存在非常大的占空间,非常大的结构体对象,则会造成内存泄露问题。

为什么要进程等待? 

 ❓为什么要进程等待

  • 为了获得子进程的退出信息(子进程的任务执行的结果怎么样用户需要知道)
  • 防止内存泄露
  1. 父进程通过等待,解决子进程退出的僵尸问题,回收系统资源(一定要考虑的)
  2. 获取子进程的退出信息,知道子进程是因为什么原因退出的(可选功能)
  • 后面有一些不用等待的场景,后面谈。

如何进程等待?

  • 父进程在子进程运行期间一般都在等待。
  • 父进程在子进程运行的期间也可以做别的事情,一般都让其等待。
  • 父进程等待子进程用系统调用函数
  • wait & waitpid 
  • man 2 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);

  • wait() 和 waitpid() 是 Unix/Linux 系统调用,用于等待一个或多个子进程的终止。成功这些函数返回一个进程pid,表示已终止的子进程的pid。如果出错,则返回-1。
  • 参数后面也会详细讲解和举例。参数暂时设为NULL。

在Unix和Linux编程中,wait(或更常见的waitpid)函数用于使父进程等待一个或多个子进程结束,并获取其结束状态。这些函数的返回值和参数在不同的上下文中有所不同,但我会为你解释它们的基本含义。

waitpid 函数

waitpid函数的原型如下:

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

参数:

  • pid:要等待的子进程的ID。如果pid小于-1,则等待任何组ID等于abs(pid)的子进程。如果pid等于-1,则等待任何子进程。如果pid为0,则等待与调用进程同组的任何子进程。如果pid大于0,则等待进程ID等于pid的子进程。
  • status:一个指向整数的指针,该整数将接收关于子进程状态的信息。你可以使用宏(如WIFEXITEDWEXITSTATUSWIFSIGNALEDWTERMSIG等)来检查这个状态值。
  • options:影响函数行为的选项。常见的选项有WNOHANG(如果子进程没有结束,则立即返回),WUNTRACED(如果子进程因信号而停止,则也返回),以及WCONTINUED(如果子进程因SIGCONT信号而恢复,则也返回)。

返回值:

  • 如果成功,waitpid返回等待的子进程的PID。
  • 如果设置了WNOHANG并且没有子进程可用,则返回0。
  • 如果发生错误,则返回-1,并设置errno以指示错误。

wait 函数

wait函数是waitpid函数的一个特例,它仅等待任何子进程结束,而不提供额外的选项。

其原型如下:

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

这个函数的参数和返回值与waitpid类似,但没有pidoptions参数。

总的来说,waitwaitpid函数用于在父进程中同步子进程的结束,并获取其状态信息。这在需要处理子进程输出、检查其退出状态或确保子进程正确结束的场景中非常有用。

 

wait 

  • 请看下面代码☞☞
  • 父进程等待子进程耗费的时间❓
  • fork之后创建子进程,父子进程是同时执行各自的任务吗❓
  • main函数没有return或者exit也会终止吗❓
  • 子进程运行5ms退出,进程终止了
  • 父进程在子进程运行5ms是也sleep5ms,子进程终止之后,继续sleep5ms
  • 这里就存在一个5ms的窗口时间:子进程已经终止了,父进程还在休眠,短暂的看到子进处于僵尸状态,Z状态。
  • 当父进程结束休眠,等待子进程,可以看到子进程的僵尸状态消失了且PCB被回收了。
  • 以上就证明了等待是会解决子进程的僵尸问题的
  • 等待的本质就是:获取子进程退出信息(退出码&退出信号)并让OS把PCB释放掉(就是把子进程的Z状态☞X状态)
 myprocess.c  
  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7 
  8 void ChildRun()
  9 {
 10   int cnt = 5;
 11   while(cnt--)
 12   {
 13     printf("I am child,pid: %d,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);
 14     sleep(1);                                                                                      
 15   }
 16 }
 17 
 18 int main()
 19 {
 20   printf("I am father,pid: %d,ppid: %d\n",getpid(),getppid());//父进程
 21   pid_t id = fork();
 22   if(id == 0)//child子进程
 23   {
 24     //子进程循环运行
 25     ChildRun();
 26     printf("Child quit...\n");
 27     exit(0);//终止进程,子进程直接僵尸
 28   }
 29   //子5s
 30   //父10s
 31   //father父进程,父进程在子进程运行期间先休眠10s再等待子进程....                                  
 32   sleep(10);
 33   pid_t rid = wait(NULL);
 34   if(rid > 0)
 35   {
 36     printf("wait success,rid: %d\n",rid);
 37   }
 38   sleep(3);
 39   printf("father quit ... \n");
 40 }

 

阻塞等待 

  • 我们修改以下代码,请看☞☞ 
  • 父进程在子进程运行期间5ms,一直在等待,没有做任何其他的事情。
  • 只有当子进程终止时(状态变化S☞☞Z时),父进程通过系统调用接口wait等待子进程,拿到子进程的PCB中的退出信息,告诉OS释放掉PCB。
  • 子进程没有终止之前,父进程一直处于阻塞等待中........
  • 子进程本身就是软件,父进程的本质时在等待某种软件条件就绪......(子进程终止,状态从S☞☞Z)
  • 前面我们也讲过阻塞状态,是某个进程等待硬件资源就绪,等待被调度,此进程的PCB处于该硬件资源的等待队列中,该进程处于阻塞状态。(类似理解)
  • 一个进程等待某种资源就绪
  1. 硬件资源就绪
  2. 软件条件就绪

如何理解父进程阻塞等待子进程条件就绪呢❓

  • 阻塞等待子进程
  • 父进程不在被调度,父进程的状态设为S状态。(休眠状态)
  • 父进程的PCB被链入到子进程的等待队列中。
  • 一旦子进程终止.....
  • OS就把等待队列中的父进程唤醒,父进程的状态设为R状态(运行状态)。
  • 继续向后执行。
  • 注意❗无论是硬件还是软件在操作系统OS中都是数据结构的对象,一切皆对象。(这个在后面C++中也会讲到)
myprocess.c
  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7 
  8 void ChildRun()
  9 {
 10   int cnt = 5;
 11   while(cnt--)
 12   {
 13     printf("I am child,pid: %d,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);
 14     sleep(1);
 15   }
 16 }
 17 
 18 int main()
 19 {
 20   printf("I am father,pid: %d,ppid: %d\n",getpid(),getppid());//父进程
 21   pid_t id = fork();
 22   if(id == 0)//child子进程
 23   {
 24     //子进程循环运行
 25     ChildRun();
 26     printf("Child quit...\n");
 27     exit(0);//终止进程,子进程直接僵尸
 28   }        
 29   //father
 30   //父进程,父进程在子进程运行期间5ms一直在等待....
 31   pid_t rid = wait(NULL);
 32   if(rid > 0)                                                                                      
 33   {
 34     printf("wait success,rid: %d\n",rid);
 35   }
 36   sleep(3);
 37   printf("father quit ... \n");
 38 }
                             

🙂感谢大家的阅读,若有错误和不足,欢迎指正。下篇讲解重点waitpid&非阻塞等待。

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

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

相关文章

在国企分公司做信息宣传新闻投稿的经验分享

作为一名国企分公司的信息宣传工作者,我亲历了从传统投稿方式到数字化转型的全过程,这段经历既充满了挑战,也收获了成长。回首最初的日子,那些用邮箱投稿的时光,至今仍让我感慨万千。 初尝辛酸,邮箱投稿的艰难岁月 刚接手信息宣传工作时,我满腔热情,却很快被现实的冷水浇了个透…

了解内存函数

✨✨欢迎&#x1f44d;&#x1f44d;点赞☕️☕️收藏✍✍评论 个人主页&#xff1a;秋邱博客 所属栏目&#xff1a;C语言 前言 内存函数不止malloc、calloc、realloc、free还有memcpy、memmove、memset、memcmp。前四个的头文件是<stdlib.h>,后四个的头文件是<strin…

哪些博客类型是最受欢迎的?

在创建博客时&#xff0c;您可能会想到的最常见的问题之一是哪些是最受欢迎的博客类型&#xff1f;有许多不同类型的博客涉及广泛的主题&#xff0c;兴趣和受众。对于一个成功的博客&#xff0c;你需要提前计划并选择适合你的利基市场。在本文中&#xff0c;我们将分享您可以立…

Navicat导出表结构到Excel或Word

文章目录 sql语句复制到excel复制到Word sql语句 SELECTcols.COLUMN_NAME AS 字段,cols.COLUMN_TYPE AS 数据类型,IF(pks.CONSTRAINT_TYPE PRIMARY KEY, YES, NO) AS 是否为主键,IF(idxs.INDEX_NAME IS NOT NULL, YES, NO) AS 是否为索引,cols.IS_NULLABLE AS 是否为空,cols.…

OpenMV 图像串口传输示例

注意&#xff1a;本程序根据 OpenMV采集图片通过串口发送&#xff0c;PC接收并保存为图片 更改。 一、例程说明 这个例程主要实现了以下功能: 1. OpenMV 端采集图像:使用OpenMV开发板上的摄像头采集实时图像数据。 2. 通过串口传输图像数据:将采集到的图像数据打包成字节流,…

Github使用教程(流畅登录)

『教程』手把手教你流畅访问Github_哔哩哔哩_bilibili 根据以上视频整理。 1)uu.163.com 下载加速器 2&#xff09;搜索学术资源 3&#xff09;会弹出这个网页 4&#xff09;此时再从github上下载项目会变快 5&#xff09;下载完成后&#xff0c;结束加速。 视频中还分享…

Springboot+vue项目健身房课程预约平台

开发语言&#xff1a;Java 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:springbootvue JDK版本&#xff1a;jdk1.8 本系统主要实现了首页、个人中心、用户管理、教练管理、会员卡管理、购买会员管理、课程类型管理、课程信息管理、课程购买…

Spring Task及订单状态定时处理

1&#xff1a;Spring Task概念&#xff1a; Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑 定时任务的理解 定时任务即系统在特定时间执行一段代码&#xff0c;它的场景应用非常广泛&#xff1a; 购买游戏的月卡会员后&a…

数据结构-线性表-链表-2.3-6

有一个带头结点的单链表L&#xff0c;设计一个算法使其元素递增有序。 void sort(Linklist &L){LNode *pL->next,*pre;LNode *rp->next;p->nextNULL;pr;while(p){rp->next;preL;while(pre->next!NULL&&pre->next->data<p->data){prepre…

最新AI实景自动无人直播软件:智能讲解、一键开播,享受24小时自动专业直播体验

在现今数字化时代&#xff08;ai无人直播下载&#xff1a;hzzxar&#xff09;直播行业越来越受到人们的关注和喜爱。随着人工智能的不断发展&#xff0c;AI实景自动无人直播软件应运而生&#xff0c;为商家提供了更便捷、高效的直播方式。本文将介绍如何利用这一创新技术&#…

Flutter笔记:美工设计.导出视频到RIVE

Flutter笔记 美工设计.导出视频到RIVE - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28…

图像处理之SVD检测显示屏缺陷(C++)

图像处理之SVD检测显示屏缺陷&#xff08;C&#xff09; 文章目录 图像处理之SVD检测显示屏缺陷&#xff08;C&#xff09;前言一、SVD算法简介二、代码实现总结 前言 显示屏缺陷检测是机器视觉领域的一处较广泛的应用场景&#xff0c;显示屏主要有LCD和OLED&#xff0c;缺陷类…

4.5_shell的执行流控制

##1.for语句## &#xff08;1&#xff09;for语句作用 为循环执行动作 &#xff08;2&#xff09;for语句结构 for 定义变量 do 使用变量&#xff0c;执行动作 done 结束标志 &#xff08;3&#xff09;for语句的基本格式 格式1 格式1&#xff1a;#!/b…

现身说法暑期三下乡社会实践团一个好的投稿方法胜似千军万马

作为一名在校大学生,去年夏天我有幸参与了学院组织的暑期大学生三下乡社会实践活动,这段经历不仅让我深入基层,体验了不一样的生活,更是在新闻投稿的实践中,经历了一次从传统到智能的跨越。回忆起那段时光,从最初的邮箱投稿困境,到后来智慧软文发布系统的高效运用,每一步都刻印…

(六)JSP教程——out对象

out对象是在JSP中经常使用到的对象&#xff0c;它本质上是一个输出流&#xff0c;前面已经多次使用&#xff0c;我们经常使用它的print()和println()方法&#xff0c;这些方法主要用于实现客户端数据的输出。通过out对象也可以直接向客户端发送一个由程序动态生成的HTML文件。 …

PPPoE实验新手必备:从0到1的网络配置指南!

5月18日&#xff0c;思科华为初级网工课程&#xff0c;等你免费试听 V&#xff1a;glab-mary 今天带大家学习一下华为PPPoE实验配置 01、实验拓扑 02、实验需求 1.完成PPP封装 2.完成PPP的PAP验证 3.完成PPP的CHAP验证 4.完成R1和R2之间的PPPOE 03、实验步骤 a . PPP封…

内存卡罢工,数据危机?别急,有救!

在日常生活和工作中&#xff0c;我们越来越依赖于各种电子设备来存储重要数据。其中&#xff0c;内存卡因其便携性和大容量而广受欢迎。然而&#xff0c;当内存卡突然损坏打不开时&#xff0c;我们该如何应对&#xff1f;本文将为您详细解析这一问题&#xff0c;并提供有效的解…

c语言实现贪吃蛇小游戏————附全代码!!!

目录 1.Win32 API 1.1控制台应用程序 1.2控制台的名称&#xff0c;控制台窗口大小 1.3设置控制台光标位置 COORD - 光标坐标 GetStdHandle - 获取句柄 SetConsoleCursorPosition - 设置光标位置 封装一个设置光标的函数 1.4设置控制台光标的属性 CONSOLE_CURSOR_INFO …

Cargo - 构建 rust项目、管理依赖包

文章目录 关于 Cargo构建项目创建工程编译运行buildclean 管理依赖添加依赖updatecheck计时 manual rust 安装可参考&#xff1a;https://blog.csdn.net/lovechris00/article/details/124808034 关于 Cargo Cargo 官方文档 &#xff1a; https://doc.rust-lang.org/cargo/crat…

泛型编程四:容器

文章目录 前言一、序列容器verctor 总结 前言 STL有六大部件&#xff0c;容器、算法、仿函数、迭代器、适配器和分配器。除了算法是函数模板&#xff0c;其他都是类模板。容器可以分为序列容器和关联容器。常见的序列容器有vector、array、deque、list、forward-list&#xff…