【Linux学习】深入探索进程等待与进程退出码和退出信号

文章目录

  • 退出码
    • return退出
  • 进程的等待
    • 进程等待的方法


退出码

main函数的返回值:进程的退出码。
一般为0表示成功,非0表示失败。
每一个非0退出码都表示一个失败的原因;

echo $?命令

作用:查看进程退出码。(最近一次进程退出时的退出码)
在这里插入图片描述

查看进程的退出码对应的错误描述:

  1. 使用系统自带函数:strerror
    作用:将一个错误吗转化为错误描述。
    在这里插入图片描述

示例:

测试代码:

   #include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>int main(){for(int i =0 ;i<200;i++){printf("%d: %s\n",i,strerror(i));                                                                                        }return 0;}

运行结果:
在这里插入图片描述

  1. 自定义
   enum{success=0,Operation_not_permitted, No_such_file_or_directory };const char* errorstr(int error){switch(error){case success: return "success";case Operation_not_permitted: return "Operation not permitted";case No_such_file_or_directory: return "No such file or directory";default:return "unkown";}}

除了进程退出,还有函数退出,怎么知道函数的执行情况? 函数返回值。

函数返回值

调用函数我们通常想看到两种结果:

  1. 函数的执行结果------函数返回值

  2. 函数的执行情况------成功 ,失败及什么原因

    就比如fopen函数:
    如图:翻译:如果打开成功,返回该文件指针,如果失败,返回NULL,并且会设置一个错误码,名字叫errno,表明失败原因
    在这里插入图片描述

示例:
测试代码:

#include<stdio.h>
#incldue<stdlib.h>
#incldue<errno.h>
int main()
{FILE* fp = fopen("./c.txt","r");printf("%d:%s\n",errno,strerror(errno));return 0;
}

运行结果:
在这里插入图片描述

函数exit :终止进程。
使用:exit(退出码)。

exit与_exit的区别:exit会支持刷新缓冲区,而_exit不支持。

示例:
测试代码一:

int main()
{printf("hello linux");sleep(2);exit(1);return 0;
}

运行结果:
在这里插入图片描述
当将上面的exit换为_exit时,运行结果如下:
在这里插入图片描述

exit与_exit的关系:exit是对_exit的封装,就是调用的_exit。
在这里插入图片描述

return退出

return是一种更常见的退出进程方法。执行 return n等同于执行exit(n),因为调用main的运行时函数会将main的返回值当做 exit的参数。

任何进程最终的执行情况,我们可以是使用两个数字表示的:1.退出码 2.退出信号

退出信号:

如图:(注意是从1开始的)
在这里插入图片描述

进程的等待

进程等待必要性

  • 子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。
  • 另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。
  • 最后,父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出。
  • 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

进程等待的方法

  1. wait方法
  • 在进行等待的时候,默认进行的是阻塞等待。
  • 返回值:
  • 成功返回被等待进程pid,失败返回-1。
  • 参数:
  • 输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
    在这里插入图片描述

测试代码:

 #include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<errno.h>#include<sys/wait.h>#include<sys/types.h>int main(){pid_t id = fork();if(id==0){//子进程int cnt = 2;while(cnt--){printf("child  pid:%d  ppid: %d\n",getpid(),getppid());                                                                sleep(1);}printf("子进程准备退出\n");exit(0);}//fatherprintf("父进程休眠\n");sleep(4);printf("父进程回收僵尸进程\n");pid_t rid = wait(NULL);if(rid>0){printf("等待成功,僵尸进程 id:%d\n",rid);}printf("父进程回收成功\n");sleep(2);return 0;}

运行结果:fork之后,父子进程谁最先运行?不确定。
谁最后退出,父进程。
在这里插入图片描述

  1. waitpid的使用在这里插入图片描述

返回值:

  • 当正常返回的时候waitpid返回收集到的子进程的进程ID;
  • 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
  • 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

参数:pid

  • Pid=-1,等待任一个子进程。与wait等效。
  • Pid>0.等待其进程ID与pid相等的子进程。

如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。
如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。
如果不存在该子进程,则立即出错返回。

测试代码:

  9 int main()10 {11   pid_t id = fork();12   if(id==0)13   {14     //子进程15     int cnt = 2;16     while(cnt--)17     {18       printf("child is running  pid:%d  ppid: %d\n",getpid(),getppid());19       sleep(1);20     }21     printf("子进程准备退出\n");22     exit(1);23   }24   int status = 0;25   pid_t rid = waitpid(id,&status,0);                                                                                                    26   if(rid>0){27     printf("等待成功,僵尸进程 id:%d status:%d\n",rid,status);28   }29   sleep(2);30 31   return 0;32 }

运行结果:
在这里插入图片描述
分析:退出码为1,这里为什么是256呢?

根据下面对status存储的解释:上面的status等于:
0000 0000 0000 0000 0000 0001 0000 0000 = 2^8 = 256

获取子进程status

wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。
如果传递NULL,表示不关心子进程的退出状态信息。
否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特位):
在这里插入图片描述


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

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

相关文章

I.MX6ULL Linux C语言开发环境搭建(点灯实验)

系列文章目录 I.MX6ULL Linux C语言开发 I.MX6ULL Linux C语言开发 系列文章目录一、前言二、硬件原理分析三、构建步骤一、 C语言运行环境构建二、软件编写三、链接脚本 四、实验程序编写五、编译下载验证 一、前言 汇编语言编写 LED 灯实验&#xff0c;但是实际开发过程中汇…

Go语言的内存泄漏如何检测和避免?

文章目录 Go语言内存泄漏的检测与避免一、内存泄漏的检测1. 使用性能分析工具2. 使用内存泄漏检测工具3. 代码审查与测试 二、内存泄漏的避免1. 使用defer关键字2. 使用垃圾回收机制3. 避免循环引用4. 使用缓冲池 Go语言内存泄漏的检测与避免 在Go语言开发中&#xff0c;内存泄…

【已解决】C#设置Halcon显示区域Region的颜色

前言 在开发过程中&#xff0c;突然发现我需要显示的筛选区域的颜色是白色的&#xff0c;如下图示&#xff0c;这对我们来说不明显会导致我的二值化筛选的时候存在误差&#xff0c;因此我们需要更换成红色显示这样的话就可以更加的明显&#xff0c;二值化筛选更加的准确。 解…

java: 无法访问org.springframework.ldap.core.LdapTemplate

完整错误&#xff1a; java: 无法访问org.springframework.ldap.core.LdapTemplate错误的类文件: /E:/apache-maven-3.6.3/repository/org/springframework/ldap/spring-ldap-core/3.2.3/spring-ldap-core-3.2.3.jar!/org/springframework/ldap/core/LdapTemplate.class类文件具…

《2024年中国机器人行业投融资报告》| 附下载

近年来&#xff0c;国内机器人行业取得了显著的技术进步&#xff0c;包括人工智能、感知技术、自主导航等技术方面的突破&#xff0c;使得机器人能够更好地适应复杂环境和任务需求&#xff0c;带动了机器人行业加快发展。 当然&#xff0c;技术的进步是外在驱动因素&#xff0…

深入探索微软Edge:新一代浏览器的演进与创新

在数字时代的浪潮中&#xff0c;浏览器已不再只是简单的网页访问工具&#xff0c;而是成为了连接信息、服务与用户之间的重要桥梁。微软Edge作为微软公司推出的一款全新的浏览器&#xff0c;不仅承载着微软在互联网领域的最新愿景&#xff0c;还融合了多项前沿技术&#xff0c;…

探索集合python(Set)的神秘面纱:它与字典有何不同?

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、集合&#xff08;Set&#xff09;与字典&#xff08;Dictionary&#xff09;的初识 1. …

L2-038 病毒溯源

详解代码 #include <iostream> #include <cstring> #include <algorithm>using namespace std;const int N 10010,M10010;int n; int h[N], e[M], ne[M], idx;//邻接表,h表示顶点&#xff0c;e表示当前边的终点&#xff0c;ne表示下一条边&#xff0c;idx当…

海外动态IP代理如何提高效率?

动态住宅IP代理之所以能够有效提升数据爬取的效率和准确性&#xff0c;主要归功于其提供的IP地址具有高度的匿名性和真实性。这些IP地址来自于真实的用户网络&#xff0c;因此相比于数据中心IP&#xff0c;它们更不容易被网站的安全系统标识为爬虫。此外&#xff0c;由于IP地址…

XSS 攻击

XSS(Cross site Scripting,跨站脚本攻击)&#xff0c;是指攻击者利用站点的漏洞&#xff0c;在表单提交时&#xff0c;在表单内容中加入一些恶意脚本&#xff0c;当其他正常用户浏览页面&#xff0c;而页面中刚好出现攻击者的恶意脚本时&#xff0c;脚本被执行&#xff0c;从而…

【vue-1】vue入门—创建一个vue应用

最近在闲暇时间想学习一下前端框架vue&#xff0c;主要参考以下两个学习资料。 官网 快速上手 | Vue.js b站学习视频 2.创建一个Vue3应用_哔哩哔哩_bilibili 一、创建一个vue3应用 <!DOCTYPE html> <html lang"en"> <head><meta charset&q…

NodeJS安装并生成Vue脚手架(保姆级)

文章目录 NodeJS下载配置环境变量Vue脚手架生成Vue脚手架创建项目Vue项目绑定git 更多相关内容可查看 NodeJS下载 下载地址&#xff1a;https://nodejs.org/en 下载的速度应该很快&#xff0c;下载完可以无脑安装&#xff0c;以下记得勾选即可 注意要记住自己的安装路径&…

【Linux】简单模拟C语言文件标准库FILE

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

Kaggle——First Machine Learning Model

kaggle&#xff08;需要魔法才能访问&#xff09;:https://www.kaggle.com/ 需要下载的数据集&#xff1a;melb_data.csv、train.csv&#xff08;已放在资源里面&#xff09; First Machine Learning Model Selecting Data for Modeling #Selecting Data for Modeling import…

C++ 学习 关于引用

&#x1f64b;本文主要讲讲C的引用 是基础入门篇~ 本文是阅读C Primer 第五版的笔记 &#x1f308; 关于引用 几个比较重要的点 &#x1f33f;引用相当于为一个已经存在的对象所起的另外一个名字 &#x1f31e; 定义引用时&#xff0c;程序把引用和它的初始值绑定&#xff08;b…

【MySQL精通之路】InnoDB磁盘I/O和文件空间管理(11)

主博客&#xff1a; 【MySQL精通之路】InnoDB存储引擎-CSDN博客 目录 1.InnoDB磁盘I/O 1.1 预读 1.2 双写缓冲区 2.文件空间管理 2.1 Pages, Extents, Segments, and Tablespaces&#xff08;很重要&#xff09; 2.2 配置保留文件段页面的百分比 2.3 页与表行的关系 …

R可视化:可发表的Y轴截断图

Y轴截断图by ggprism Y轴截断图by ggprism 介绍 ggplot2绘制Y轴截断图by ggprism加载R包 knitr::opts_chunk$set(message = FALSE, warning = FALSE)library(tidyverse) library(ggprism) library(patchwork)rm(list = ls()) options(stringsAsFactors = F) options(future.…

2024年高考考务人员网上培训参考答案

第1部分&#xff1a;单选题 1. 关于试卷保密室负责人职责&#xff0c;以下说法不正确的是&#xff08;B&#xff09; [2分] A. 负责试卷的接收、保管和发放工作 B. 试卷保密室内屋门锁钥匙和铁柜门锁钥匙必须由同一人保管 C. 试卷接收和发放应当当面清点试卷袋数量&#…

Go语言的中间件(middleware)是如何实现的?

文章目录 Go语言的中间件&#xff08;Middleware&#xff09;是如何实现的&#xff1f;中间件的工作原理中间件的实现步骤示例代码总结 Go语言的中间件&#xff08;Middleware&#xff09;是如何实现的&#xff1f; 在Go语言中&#xff0c;中间件&#xff08;Middleware&#…

springboot实现多开发环境匹配置(超级简洁没废话)

首先logbok-spring.xml里面的内容 <?xml version"1.0" encoding"UTF-8"?> <configuration><!-- 开发、测试环境 --><springProfile name"dev,test"><include resource"org/springframework/boot/logging/log…