wait/waitpid(重点)介绍

news2024/9/23 3:18:51

谢谢你的阅读,如有错误请大佬留言

目录

引子:

waitpid

返回值介绍

参数介绍

pid

status

options:


引子:

 当一个进程创建子进程后,如果子进程工作结束后会进入僵尸状态,等待父进程回收子进程资源(退出码,退出信号,子进程pid),如果父进程进入死循环或者程序执行时间过长,那么子进程将会一直处于僵尸状态,占用内存空间,这是对我们不利的一种状态,这种状态连kill -9 pid 都无法解决问题,因为你无法杀死一个以及死(Z/D,僵尸状态其实也属于死亡进程,只是未被清理)的状态。那么,如何防止这样的情况呢?

我们可以调用两个系统接口,来处理子进程僵尸状态:

pid_t wait(int *status);                                                                                                                  pid_t waitpid(pid_t pid, int *status, int options);
让我们先介绍这两个的概念。

看一下代码:

 我们的wait和waitpid的作用就是会暂停当前进程的执行,直到有信号到来或者子进程结束。总的来说,wait()的作用就是阻塞父进程,等待子进程。

但是我们的waitpid还有一种非暂停等待子进程的过程。

这里我们主要学waitpid/当我们的waitpid学习后,wait也明白了作用 

waitpid

pid_ t waitpid(pid_t pid, int *status, int options);

返回值介绍

返回值:

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

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

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

参数介绍

pid

1、(重点)pid=-1 等待任意一个子进程退出。

waitpid(-1,NULL,0);
//等待任意的子进程退出

2、(重点)pid>0 等待指定pid进程退出。

waitpid(1234,NULL,0);
//等待pid为1234的子进程退出

(次重)pid=0 等待进程组GID 与当前进程GID的子进程结束(也就是等待同一个进程组中的任何子进程);

waitpid(0,NULL,0);
//等待GID等于当前进程GID的子进程退出

(次重)pid<-1等待进程组识别码为 pid 绝对值的任何子进程。 

等待进程组 GID 为 pid 绝对值的进程组中的任何子进程;

GID 是组ID (Group Identify),表示组的身份唯一标识
UID 是用户ID (User Identify),表示用户身份唯一标识

status

先理解实现:

        int类型的指针,我们需要在调用处定义。然后传入函数,获取信息。

int sta=0;
waitpid(-1,&sta,0);//返回型参数

这里我们根据sta会取到子进程退出信号,退出码core dump等等信息。为什么一个变量可以获得这么多的信息呢?因为他是一个4字节类型,有32位比特位,所以我们分区块,获取数据,前16位比特位我们暂且不管,我们来看看后16位比特位给我们什么信息。

当进程正常退出,遇见exit/main中return。

退出码位后16位的前8位数据。(正常退出,结果正确/错误)

 如果子进程在运行期间发生越界访问或除0等严重错误时,发送信号,程序中断,这时候进程执行不到退出码,所以退出码没有意义,然后后7位为退出的信号

如何查看退出码:先右移8个比特位再位运算

int sta=0;
waitpid(-1,&sta,0);
printf("code:%d",(std>>8)&0xff);//右移后,使用位运算取到退出码
printf("code:%d",WEXITSTATUS(status));//使用宏,其实底层也是位运算,返回子进程错误码。

 如何查看退出信号:直接位运算

int sta=0;
waitpid(-1,&sta,0);
printf("code:%d",std&0x7f);//使用位运算取到退出信号,0正常退出,非0退出信号
printf("code:%d",WIFEXITED(status));//使用宏,其实底层也是位运算,
//判断子进程是否正常退出,正常返回真,非正常返回假,bool返回类型

两个宏:

WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)

WIFSIGNALED(status):如果子进程异常退出,获取退出信号,正常返回0(查看进程异常退出信号)

WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

实战使用:

正常退出:

 

异常退出 

发现正常退出时候信号为0,有退出码:123;

而异常退出的时候信号为非0,子进程提前结束无退出码;


options:

        0:若pid指定的子进程没有结束,父进程挂起。若正常结束,则返回该子进程的ID。

        WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。正常结束,则返回该子进程的ID。(异常返回-1)

                这里我们介绍一下什么是进程阻塞的概念。

阻塞:指有障碍而不能通过,无法畅通。我们waitpid一般设置为阻塞状态等待子进程返回,        但是我们也可以让进程以非阻塞状态进行等待子进程结束。我第一次理解的时候,这是什么意思?

让我们画图理解下:

A等待B去游玩,但是B在工作,A等待B完成工作

而这的等待有,两个方式:原地等待与边等边做自己的工作。

1、原地等待(阻塞状态):

if(fork()==0)
{
    //.....
    printf("子进程未结束工作\n");
    //.....
    exit(0);
}
waitpid(-1,NULL,0);//阻塞状态等待子进程结束
//....

2、边做自己的事情等待(非阻塞)

if(fork()==0)
{
    //.....
    printf("子进程未结束工作\n");
    //.....
    exit(0);
}
while(1){
    if(0==waitpid(-1,NULL,WNOHANG));//非阻塞状态等待子进程结束
    {
        //father doing own business
    }
    else
    {
        //接收到子进程pid(非0)退出等待
        break;
    } 
}
//....

 还记得wait吗

其实wait(NULL)等价于waitpid(-1,NULL,0);阻塞状态等待任意子进程结束,不需要返回值参数。

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

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

相关文章

烟花智能直播助手,直播带货必备爆单工具【直播助手脚本+技术教程】

烟花智能直播助手软件教程介绍&#xff1a; 1.账号管理:可以登陆多个账号,一键切换 2.商品批量管理&#xff1a;可一键删除/添加直播商品,一键设置商品卖点 3.自动弹讲解:可设置指定,单个,列表循环自动弹商品讲解 4.智能文字客服:可设置指定关键词对公屏信息进行回复,不限添加条…

【C语言】C语言总结

声明&#xff0c;本文来自中国mooc中的翁凯C语言总结 第一章介绍 变量定义 变量定义的一般形式为&#xff1a;<类型名称><变量名称>变量需要一个名字&#xff0c;变量的名字是一种表示符&#xff0c;意思是用来识别不同的标识符标识符的基本构造规则为&#xff…

近世代数 笔记与题型连载 第十一章(正规子群与商群)

文章目录 基本概念1.正规子群2.商群 常见题型1.正规子群的判定和证明2.给定群和正规子群&#xff0c;求商群 基本概念 1.正规子群 正规子群的定义&#xff1a;设<G,※>是群&#xff0c;H是G的子群。如果对于G中的任意元素g&#xff0c;都有gHHg&#xff0c;则称H是G的正…

org.apache.poi 设置 Excel 单元格颜色 RGB

一、背景说明 在使用 org.apache.poi 导出 Excel 时&#xff0c;需要设置部分单元格的颜色。 可以使用方法&#xff1a;org.apache.poi.ss.usermodel.CellStyle.setFillForegroundColor() 和 org.apache.poi.ss.usermodel.CellStyle.setFillPattern() 来设置单元格的颜色和填…

代码随想录 LeetCode数组篇 二分查找

文章目录 &#xff08;简单&#xff09;35. 搜索插入位置&#xff08;*中等&#xff09;34. 在排序数组中查找元素的第一个和最后一个位置&#xff08;简单&#xff0c;常见面试题&#xff09;69. x的平方根&#xff08;简单&#xff09; 367. 有效的完全平方数 # &#xff08;…

三款自研AI应用引领未来,重塑行业新风尚

在这个科技日新月异的时代&#xff0c;AI技术已经渗透到我们生活的方方面面。今天&#xff0c;我们将向您推荐三款领域独具特色的AI应用&#xff0c;它们分别是AI律师、AI小红书文案提示词、以及AI Midjourney提示词。这些应用都具有独特的内涵&#xff0c;让我们一起走进这些智…

linux--进程程序替换

目录 一、什么是进程程序替换 二、原理&#xff1a; 三、为什么要进行程序替换 四、六种替换函数 命名理解 (1)函数execl (2)函数execv (3)execlp (4)execvp (5)execle (6)execve 一、什么是进程程序替换 所谓进程程序替换&#xff0c;顾名思义&#xff0c;就是使用一个…

‘cnpm‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

文章目录 1.0 问题描述2.0 检查环境&#xff1a;2.0.1查看node 环境2.0.2 cnpm 要安装好 3.0 查看原因4.0 问题解决【配置环境变量】4.0.1 方式一4.0.2 方式二 5.0 测试成功 1.0 问题描述 ‘cnpm’ 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 2.0 检…

手动开发--简单的 Spring 基于注解配置的程序

目录 手动开发--简单的 Spring 基于注解配置的程序 需求说明 思路分析程序结构 2) 程序框架图 ● 应用实例 创建ComponentScan.java注解 创建WyxSpringConfig 创建WyxSpringApplicationContext 作用 注意 获取全类名的步骤 Class.forName和Class.loadClass的区别 手…

c++ 11标准模板(STL) std::vector (二)

定义于头文件 <vector> template< class T, class Allocator std::allocator<T> > class vector;(1)namespace pmr { template <class T> using vector std::vector<T, std::pmr::polymorphic_allocator<T>>; }(2)(C17…

马上五一了,带大家玩一下五子棋——C语言

五一祝福 因为这篇博文实在五一这天完成的&#xff0c;所以呢&#xff0c;在介绍五子棋之前&#xff0c;先祝各位支持小白的大佬都五一快乐&#xff01; 花了点时间下了个“五一快乐”的五子棋&#xff0c;哈哈哈哈哈哈&#xff0c;还不太熟练&#xff0c;所以写的有点丑&…

常用 Composition API【VUE3】

二、常用 Composition API 7. 计算属性与监视 7.1 computed函数 与Vue2.x中computed配置功能一致写法 <template><h1>一个人的信息</h1>姓&#xff1a;<input type"text" v-model"person.firstName"><br><br>名&a…

【ROS 开发神器 Visual Studio Code 的安装和设置】

【ROS 开发神器 Visual Studio Code 的安装和设置】 1. Visual Studio Code的安装1.1 点击deb文件下载1.2 安装VScode1.3 启动软件1.4 添加收藏夹 2. 导入工作空间2.1 熟悉Vscode基本界面2.2 添加工作空间 3. 安装简体中文语言4. 安装ROS插件5. 安装CMake插件6. 安装括号颜色插…

SpringBoot 中的加密模块

Spring Boot 是一款流行的 Java 开发框架&#xff0c;它提供了多种加密模块&#xff0c;用于保护数据的安全性。本文将介绍 Spring Boot 中的加密模块&#xff0c;包括对称加密、非对称加密和哈希加密等&#xff0c;同时还会提供相应的代码示例。 一、对称加密 对称加密是一种…

改进YOLOv8 | 即插即用篇 | 全维动态卷积 |《 OMNI-DIMENSIONAL DYNAMIC CONVOLUTION》

单个静态卷积核是现代卷积神经网络(CNNs)的常见训练范式。然而,最近的动态卷积研究表明,学习加权为其输入依赖注意力的n个卷积核的线性组合可以显著提高轻量级CNNs的准确性,同时保持高效的推理。然而,我们观察到现有的作品通过卷积核空间的一个维度(关于卷积核数量)赋予…

关于密码学的进一步答疑:SSL和TLS的区别、CA和CT的关系

《密码学&#xff1a;一文读懂常用加密技术原理及其逻辑与应用方法》一文一经发布后&#xff0c;后台收到了许多私信&#xff0c;承蒙喜爱&#xff0c;这篇文章将主要对后台收到的高频问题予以统一回应。 问题一: 在讨论加密解密的过程中&#xff0c;常常在同一语境下同时出现S…

设计模式之原型模式(深拷贝浅拷贝)

目录 1、什么是原型模式 2、前置知识&#xff08;深拷贝&浅拷贝&#xff09; 2.1 浅拷贝 2.2 深拷贝 3、代码实现 3.1 通过Object中的clone方法实现浅拷贝 3.2 通过对象流来实现深拷贝 4、原型模式总结 4.1 优缺点 4.2 使用场景 4.3 对比直接new对象有何不同 1、…

如何使用递归函数实现Excel列号转换列标

在Excel中&#xff0c;列标与列号转换是VBA开发过程中经常用到的功能&#xff0c;下面这篇博客为大家解释了多种方法。 【Excel列标与列号转换】 那么这篇博文的核心是“递归过程”&#xff0c;实现这个功能并不是必须使用递归过程&#xff0c;但是这也不失为一种实现方法&am…

【Android入门到项目实战-- 8.2】—— 使用HTTP协议访问网络

目录 一、使用HttpURLConnection 1、使用Android的HttpURLConnection步骤 1&#xff09;获取HttpURLConnection实例 2)设置HTTP请求使用的方法 3)定制HTTP请求&#xff0c;如连接超时、读取超时的毫秒数 4)调用getInputStream()方法获取返回的输入流 5)关闭HTTP连接 2、…

NXP - LPC1769与LPC1768的区别

文章目录 NXP - LPC1769与LPC1768的区别概述笔记General description验证结论END NXP - LPC1769与LPC1768的区别 概述 openpnp设备用到了冰沙主板. 冰沙主板的主控MCU用到了LPC1769, 想着研究一下. 订了OM13085UL, 遥遥无期… 买了LPC MCU的书, 里面提到了书的作者的网店, 居…