当前位置: 首页 > news >正文

Linux 进程终止和等待

目录

一:进程常见的退出方法

1. main 函数返回值 

2.调用 exit 

3.调用 _exit

二:异常问题

三:进程等待

1.概念

2.进程等待的必要性

3.进程等待的方法

<1>:wait --- 系统调用

<2>:waitpid


进程退出场景:

  • 代码运行完毕,结果正确
  • 代码运行完毕,结果不正确
  • 代码异常终止

一:进程常见的退出方法

正常终止(通过 echo $? 查看进程退出码):

<1>: 从 main 返回

<2>: 调用 exit 

<3>: 调用_exit

异常退出:

ctrl + c , 信号终止

1. main 函数返回值 


echo $?

?:保存的是最近一个子进程执行完毕时的退出码。


 测试代码:

#include<stdio.h>
int main()
{printf("hahahagehe\n");return 10;
}

 编译并运行代码,然后查看进程的退出码:

 6d496c1d16d54c0b86878a0fe27d690f.png

上述现象表明:main 函数的退出码是可以被父进程获取的,用来判断子进程的运行结果。


在C语言中我们学习过错误码,那么错误码和退出码有什么区别呢???

错误码:通常是衡量一个库函数/一个系统调用一个函数的调用情况,当失败的时候,用来衡量函数进程出错的出错原因。

退出码:通常是一个进程退出的时候,它的退出结果。


2.调用 exit 


通过 man 2 exit ,命令 exit 信息 

3549da59d26344788584ebf4629fbde8.png


 通过下述示例对比进行分析:

14cad97051a64a3c9184336688892799.png

在其他函数中进行 return ,表示的是函数调用结束(进程不结束)。

d5b0fdbb8d3447a3a09798de47ffe1a0.png

通过 echo $? 查看上述进程的退出码: 

 1cfe6e45287d4363b722a3712bed2167.png

 我们发现进程的退出码为 10,即函数中 exit 的返回值。由此,我们可以得出结论:

在任意地点调用 exit ,表示进程退出,不进行后续执行。

3.调用 _exit

b9cf8b907803467bb4f88f03af0ca7d0.png


那么, exit 和 _exit 的区别在哪里??? 

exit:终止进程的时候,会自动刷新缓冲区

 aace04d300264b4497188a89f866b29a.png

_exit :终止进程的时候,不会自动刷新缓冲区

 9940926eedf2437ba6c36a67f4f50419.png


二:异常问题

进程出异常,本质是进程收到了对应的信号,自己终止了!!! --->

所以一个进程是否出异常,我们只要看有没有收到信号即可。

通过判断进程的退出码。

进程退出的三种场景中,有 :代码运行完毕,结果正确代码运行完毕,结果不正确代码异常终止 3 种,其中前两种中的结果是否正确是由我们判断的,那么这个我们指的是谁???

在多进程环境中,我们创建子进程的目的是为了让子进程帮我们做事,我们需要得知子进程把事情做的怎末样(这里的我们指的就是父进程) ---> main 函数的返回值叫做进程的退出码,0表示成功,非0表示失败。

三:进程等待

1.概念

通过 wait / waitpid 的方式,让父进程(一般)对子进程进行资源回收的等待过程。

2.进程等待的必要性

<1>:解决子进程僵尸问题带来的内存泄漏

<2>:父进程创建子进程,是要子进程来帮忙完成任务,子进程任务完成的怎末样,父进程要知道,通过进程等待的方式,获取子进程退出的信息 --- 两个数字! --- 不是必须的,但是系统需要提供这样的基础功能。

3.进程等待的方法

<1>:wait --- 系统调用

wait --- 等待任意一个子进程

f962cae702e9444db1596dfd99e7aac4.png

返回值: 成功返回被等待进程pid,失败返回-1。

参数:输出型参数,获取子进程退出状态,不关心则可以设置成为NULL。

测试下述示例: 

#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{pid_t id = fork();if(id == 0){//子进程int ret = 5;while(ret){printf("i am child\n");sleep(1);ret--;}exit(0);}else {sleep(10);//父进程pid_t rid = wait(NULL);if(rid == id){printf("wait success\n");}}return 0;
}

 监视命令行脚本:

while :;do ps ajx|head -1 && ps ajx | grep myprocess | grep -v grep;sleep 1;echo "#############################################################";done

测试现象为:

QQ录屏20230110123134


 wait :进程等待能回收子进程僵尸状态 Z ---> X,如果子进程根本就没有退出,父进程就必须在  wait 上进行堵塞等待,直到子进程僵尸, wait 自动回收,返回。

一般而言父子进程谁先运行不知道,但是最后一般都是父进程最后退出!!!


<2>:waitpid

waitpid --- 获取退出信息

147b901f14c94adeb8c407a6f3e2ac74.png

返回值:

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

参数:

pid:
  • Pid=-1,等待任一个子进程。与wait等效。
  • Pid>0.等待其进程ID与pid相等的子进程。
status:
  • WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
  • WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

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

对 wait 示例中的代码稍作修改,观察现象:

3db09eed9926488482f5601ce1bf0830.png   

获取子进程 status

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

测试示例(代码跑完结果不正确):

#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{pid_t id = fork();if(id == 0){//子进程int ret = 3;while(ret){printf("i am child\n");sleep(1);ret--;}exit(8);}else {printf("wait before\n");int status = 0;//父进程pid_t rid = waitpid(id,&status,0);printf("wait after\n");if(rid == id){printf("wait success: pid: %d,rid: %d,exit sig: %d,exit code: %d\n",getpid(),rid,status&0x7F,(status >> 8)&0xFF);}sleep(5);}return 0;
}

运行效果:

044b6d1c5c3240a09e73b979d3de16e9.png

示例(代码跑完,结果正确):

    if(id == 0){//子进程int ret = 3;while(ret){printf("i am child\n");sleep(1);ret--;}exit(0);}

运行效果:

b0d0f3d2dcf644d1a192be96131a5c49.png

示例(代码异常):

    if(id == 0){//子进程int ret = 3;int a = 5;while(ret){printf("i am child\n");sleep(1);a /= 0;ret--;}}

运行效果:

1fec9afa2d044644a77495e4e1e3a8fb.png

上述示例,出异常,但退出码为0!!!

说明一个进程异常了(收到信号),它的退出码就没有意义了。

那么如何判断适度收到了信号呢???通过 kill -l 查看,exit sig = 0; 表示正常。


父进程如何得知子进程的退出信息? 

wait / waitpid (系统调用接口)

子进程退出的时候,要修改状态Z。并将子进程的退出信号和退出码写入 pcb 中,task_struct -->

exit_code,exit_signal ---> int * stausp 指向 int status。


options:  

0:阻塞等待

WNOHANG:等待的时候,以非阻塞的方式等待

  • rid > 0 ,等待成功 break
  • rid = 0 ,等待是成功的,但是对方还没有退出 --> 做自己的事情。--- 循环
  • rid < 0 ,等待失败 break

测试代码(正常退出):

#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{pid_t id = fork();if(id == 0){//子进程int ret = 3;while(ret){printf("i am child,pid: %d ,ppid: %d ,ret: %d\n",getpid(),getppid(),ret);sleep(1);ret--;}exit(0);}//父进程while(1){int status = 0;pid_t rid = waitpid(-1,&status,WNOHANG);if(rid > 0){printf("child quit success,exit code:%d ,exit sig:%d\n",(status>>8)&0xFF,status&0x7F);break;}else if(rid < 0){printf("wait failed!!!\n");break;}else {printf("--------------------------------------------------\n");//等待成功,但子进程没有退出printf("child is alive,wait again,father do other thing ....\n");//父进程做自己的事情printf("--------------------------------------------------\n");}sleep(1);}return 0;
}

运行效果为:

修改 waitpid 部分的内容:

pid_t rid = waitpid(100,&status,WNOHANG);

运行效果为:

 


相关文章:

Linux 进程终止和等待

目录 一&#xff1a;进程常见的退出方法 1. main 函数返回值 2.调用 exit 3.调用 _exit 二&#xff1a;异常问题 三&#xff1a;进程等待 1.概念 2.进程等待的必要性 3.进程等待的方法 <1>&#xff1a;wait --- 系统调用 <2>&#xff1a;waitpid 进程…...

python用tkinter随机数猜数字大小

python用tkinter随机数猜数字大小 没事做&#xff0c;看到好多人用scratch做的猜大小的示例&#xff0c;也用python的tkinter搞一个猜大小的代码玩玩。 猜数字代码 from tkinter import * from random import randint# 定义确定按钮的点击事件 def hit(x,y):global s_Labprint(…...

程序员们保住自己饭碗

在现代社会中&#xff0c;程序员扮演着至关重要的角色。他们不仅仅是编写代码的人&#xff0c;更是保障数字世界安全稳定的守护者。随着科技的迅猛发展&#xff0c;程序员保住自己饭碗的护城河变得愈发重要。本文将探讨程序员如何通过不断学习、技术创新和软实力的发展&#xf…...

顶板事故防治vr实景交互体验提高操作人员安全防护技能水平

建筑业在我国各行业中属危险性较大且事故多发的行业&#xff0c;在建筑业“八大伤害”(高处坠落、坍塌、物体打击、触电、起重伤害、机械伤害、火灾爆炸及其他伤害)事故中&#xff0c;高处坠落事故的发生率最高、危险性极大。工地现场培训vr坠落体验利用虚拟现实技术还原各种情…...

为什么推荐从Linux开始了解IT技术

IT是什么&#xff0c;是干什么的呢&#xff1f; 说起物联网&#xff0c;云计算&#xff0c;大数据&#xff0c;或许大家听过。但是&#xff0c;你知道&#xff0c;像云计算的底层基座是什么呢&#xff1f;就是我们现在说的Linux操作系统。而云计算就是跑在Linux操作系统上的一个…...

【Mysql】增删改查(基础版)

我使用的工具是Data Grip &#xff08;SQLyog Naivact 都行&#xff09; 使用Data Grip创建student表&#xff0c;具体步骤如下&#xff08;熟悉Data Grip或者使用SQLyog&#xff0c;Naivact可以跳过&#xff09; https://blog.csdn.net/m0_67930426/article/details/13429…...

文件夹找不到了怎么恢复?4个正确恢复方法分享!

“我在电脑上保存了很多的文件和文件夹&#xff0c;今天在查找文件时&#xff0c;发现我有一整个文件夹都消失了&#xff0c;不知道怎么才能找到呢。有朋友可以帮帮忙吗&#xff1f;” 电脑中文件夹突然找不到了可能会引发焦虑&#xff0c;尤其是如果这些文件夹包含重要的数据。…...

迅为RK3568开发板GPS模块测试实验步骤

1 首先按照上个实验&#xff0d;串口实验&#xff0c;在设备树中打开串口 9 的节点。 2 然后将 GPS 模块连接好之后&#xff0c;用 U 盘将 GPS 测试程序 gps_test 拷贝到开发板的/mnt 目录下。本小节的测试程序存放路径为“iTOP-3568 开发板\02_ 【iTOP-RK3568 开发板】开发资…...

用趋动云GPU部署自己的Stable Diffusion

注&#xff1a;本文内容来自于对DataWhale的开源学习项目——免费GPU线上跑AI项目实践的学习&#xff0c;参见&#xff1a;Docs&#xff0c;引用了多处DataWhale给出的教程。 1.创建项目 1&#xff09;进入趋动云用户工作台&#xff0c;在当前空间处选择注册时系统自动生成的…...

nfs配置

1.NFS介绍 NFS就是Network File System的缩写&#xff0c;它最大的功能就是可以通过网络&#xff0c;让不同的机器、不同的操 作系统可以共享彼此的文件。 NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文 件系统中&#xff0c;而在本地端的系统中来看&#…...

说话人识别声纹识别CAM++,ECAPA-TDNN等算法

参考:https://www.modelscope.cn/models?page=1&tasks=speaker-verification&type=audio https://github.com/alibaba-damo-academy/3D-Speaker/blob/main/requirements.txt 单个声纹比较可以直接modelscope包运行 from modelscope.pipelines import pipeline sv_pi…...

某平台简单尝试一次密码逆向

1、查看表单数据 发现密码加密 2、控制台搜索password 发现他在欺负我看不懂拼音 3、第一次断点调试失败 断点后随便填写账号密码登录&#xff0c;发现失败 4、控制台搜索 jiami 又找到了一个函数 5、断点成功 重新登录后断点成功 jiami function(password) {var e passw…...

微信号绑定50个开发者小程序以后超额如何删除不用的

我们在开发微信小程序的时候&#xff0c;当前开发者工具登录的必须是该小程序的开发者才能进行小程序的开发&#xff0c;添加开发者的步骤是&#xff1a; 添加开发者 1、进入微信开放平台&#xff0c;然后扫码进入管理平台 2、找到下图所示位置 3:、输入要添加的微信账号&am…...

【Cheat Engine7.5】基础教程第三关(步骤4)

文章目录 一、简介二、操作步骤2.1、加载进程2.2、查找健康数据2.2.1、首次扫描(单浮点数100)2.2.2、点击打我&#xff0c;再次扫描数值97.112.2.3、修改数据值为50002.2.4、测试正常 2.3、查找弹药数据2.3.1、双浮点数1002.3.2、点击开火2.3.3、修改数据2.3.4、测试 2.4、通关…...

141. 环形链表 --力扣 --JAVA

题目 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xf…...

电子元器件的结温壳温与环境温度经验总结

🏡《电子元器件学习目录》 目录 1,概述2,温度定义2.1结温2.2壳温2.3环境温度3,换算与设计经验原则3.1经验原则3.2换算公式3.2.1,结温与环境温度3.2.2,结温与壳温4,总结1,概述 随着电路功能和性能的提升,单位电路板面积内的电子元器件越来越密集,电子元器件的温度成为…...

Spring Gateway基础知识总结

本文主要总结Spring Gateway的基础用法&#xff0c;内容包括网关、Spring Gateway工作流程、Spring Cloud Gateway搭建、路由配置方式、负载均衡实现、断言工厂这几个部分 目录 1. 网关 1.1 网关介绍 1.2 网关对比 1.3 Spring Gateway 1.4 核心概念 1.6 总结 2. Spring …...

NFS文件系统共享服务器实战

架设一台NFS服务器&#xff0c;并按照以下要求配置 准备 两台Linux虚拟机一台作为服务端server&#xff0c;一台作为客户端client server IPV4&#xff1a;192.168.110.136/24 client IPV4&#xff1a;192.168.110.134/24 两台服务器都需要关闭防火墙和seLinux 服…...

CSS的概念和基本用法

CSS的作用&#xff1a; 页面美化和布局控制。 1.概念&#xff1a; Cascading Style Sheets 层叠样式表。 层叠&#xff1a;多个样式可以作用在同一个html的元素上&#xff0c;同时生效。 2.好处&#xff1a; (1).功能强大 (2).将内容展示和样式控制分离 * 降低耦合度&#xf…...

万字详解Java的三大特性:封装 | 继承 | 多态

前言&#xff1a;面向对象程序设计的三大特征就是&#xff1a;封装&#xff0c;继承&#xff0c;多态。在前文介绍了类和对象后&#xff0c;我们就可以继而学习什么是封装&#xff0c;怎么用类的子类来实现继承和多态 目录 一.面向对象的特性 1.封装性 2.继承性 3.多态性…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...