【Linux】进程(9):进程控制1

news2024/12/24 3:26:47

大家好,我是苏貝,本篇博客带大家了解Linux进程(9)进程控制1,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • 1 fork函数
  • 2 进程终止
    • (A)终止是在做什么?
    • (B)退出码
    • (C)进程退出的3种情况
    • (D) 如何终止进程
      • 1. main函数return表示进程终止(非main函数return表示函数结束)
      • 2. 代码调用exit函数
      • 3. _exit函数 ---系统调用

1 fork函数

在这里插入图片描述

如果fork出错,那就不创建子进程,给父进程返回-1

为什么给父进程返回的是子进程的pid?
为了让父进程方便对子进程进行标识,进而进行管理

如何理解进程具有独立性?
进程=内核的相关管理数据结构(task_struct+mm_struct+页表)+代码和数据。对于不是父子进程的多个进程,上面的5个都不同,自然具有独立性。对于父子进程,task_struct自然不同;子进程的mm_struct和页表都是拷贝父进程的,但每个进程都有自己独立的mm_struct和页表,所以也互不影响;代码是共享的,也是只读的,所以父子进程互不影响;对于数据:父子不写入时,数据也是共享的;如果其中一个进程想要对数据进行写入,会发生写时拷贝,因此父子进程也互不影响。所以,父子进程也具有独立性,所以进程具有独立性

2 进程终止

(A)终止是在做什么?

  1. 释放曾经的代码和数据所占据的空间
  2. 释放内核数据结构(mm_struct和页表)的空间,但是task_struct会维持一段时间,变成Z状态(僵尸状态),进程要维持自己的退出信息,退出信息位于task_struct中,未来让父进程进行读取

(B)退出码

退出码是在进程执行结束后,系统返回给使用者的一个数值,用以表示进程的执行状态。main函数最后的return后面的数字是退出码。
在这里插入图片描述

所以上面代码的退出码就是0,那如何查看退出码呢?用echo $?命令,Linux提供了一个专门的变量?来保存父进程获取的,最近一个子进程的退出码
在这里插入图片描述

修改.c文件
在这里插入图片描述

退出码应该为100

在这里插入图片描述

上面说,?是保存父进程获取的,最近一个子进程的退出码,那为什么第二次?的值是0呢?
在这里插入图片描述

第二次的?是保存第一个echo $?的退出码,虽然echo不是bash的子进程,但也是由bash执行的,所以照样可能会影响退出码。因为第一个echo $?运行成功,所以退出码为0

退出码有什么用呢?
告诉关心方(一般为父进程),进程把任务完成的怎么样了。
如果退出码为0,表示程序运行成功;为!0,表示失败。不同的!0值,一方面表示失败,一方面也表示失败的原因,即有对应的错误描述

现在我们来看看退出码对应的错误描述

先看strerror函数,作用:返回错误码的字符串描述。参数是错误码
在这里插入图片描述

修改.c文件
在这里插入图片描述
在这里插入图片描述

0表示成功,1表示操作不被允许,2表示没有该文件或目录……

关于退出码,我们可以选择使用系统默认的,也可以使用我们自定义的。
我们来试试用自定义的退出码

修改.c文件
在这里插入图片描述
在这里插入图片描述

但我们发现,如果result==-1,我们不能确定是y0还是y!=0,x/y-1

修改.c文件
在这里插入图片描述

如果result==-1,错误码== 1,那么说明y== 0。如果result==-1,错误码== 0,说明x/y ==-1
在这里插入图片描述

因此,退出码可以确定代码跑完,结果是否正确。所以,你是否感觉到以前写的代码都不是很规范呢?有没有正确使用退出码呢?

(C)进程退出的3种情况

  1. 代码跑完,结果正确
  2. 代码跑完,结果不正确
  3. 代码执行时,出现异常,提前退出了

前2个可以根据退出码判断,就不再赘述了。现在我来看看第3种情况:代码执行时,出现异常,提前退出了

我们之前在写代码的时候,一定遇到过程序崩溃的情况吧。崩溃是语言层面说的,在系统层面,是因为操作系统发现你的进程做了不该做的事情,所以将进程杀掉了。

所以进程出异常的本质是因为进程收到了OS发给进程的信号

现在我们来用野指针让进程出异常
在这里插入图片描述
在这里插入图片描述

出现异常,并报错:Segmentation fault,表示段错误。OS提前终止进程

上面说,进程出异常的本质是因为进程收到了OS发给进程的信号,现在让我们来感受一下

修改.c文件
在这里插入图片描述

该进程正常来讲的话,是不会有异常的

再使用kill的11号信号
在这里插入图片描述
在这里插入图片描述

此时尽管代码没有错误,但是由于进程收到了系统的信号,所以判断是 Segmentation fault,段错误标识,进程提前终止了。因此我们也可以感受到进程出异常是因为进程收到了OS发给进程的信号

因此,我们可以通过看进程退出的时候,退出信号是什么,来判断我的进程为什么异常了。如果进程没有异常,代码跑完了,那退出信号为0
请问,如果进程出现异常,提前退出了,那还需要知道退出码吗?不用了,进程出现异常,退出码就没有意义了

如何确定程序退出是3种情况的哪一种呢?

  1. 先确认是否异常
  2. 不是异常,就是代码跑完了,看退出码判断结果是否正确

结论:衡量一个进程退出,我们只需要知道2个数字:退出码和退出信号
退出码为0,退出信号为0,代码跑完了,结果正确
退出码为!0,退出信号为0,代码跑完了,结果不正确
退出码为0,退出信号为!0,进程出现异常
退出码为!0,退出信号为!0,进程出现异常

一个进程结束,系统会释放它对应的代码和数据的空间,释放内核数据结构(mm_struct和页表),但是task_struct会维持一段时间,变成Z状态(僵尸状态),系统会将进程的退出码和退出信号写入进程的task_struct中,等待父进程进行读取

(D) 如何终止进程

1. main函数return表示进程终止(非main函数return表示函数结束)

2. 代码调用exit函数

先了解exit函数,作用:让一个正常的进程终止,参数是退出码
在这里插入图片描述

修改.c文件
在这里插入图片描述

退出码:123
在这里插入图片描述

上面说,main函数return表示进程终止(非main函数return表示函数结束)。那如果是在非main函数中调用exit函数,是表示函数结束还是进程终止呢?

修改.c文件
在这里插入图片描述

运行程序,先进入Div函数,因为100!=0,所以执行代码exit(13)
在这里插入图片描述

进程并没有打印main函数的printf函数里的内容,所以在非main函数中调用exit函数,是进程终止。
所以在代码的任意位置调用exit函数,都表示进程退出

3. _exit函数 —系统调用

先了解一下_exit,作用:终止进程,参数也是退出码
在这里插入图片描述

修改.c文件
在这里插入图片描述
在这里插入图片描述

进程也没有打印main函数的printf函数里的内容,所以在代码的任意位置调用_exit函数,都表示进程退出

那exit函数和_exit函数有什么不同吗?

修改.c文件
在这里插入图片描述
在这里插入图片描述

结果:先等待2秒,再打印出”hello world”,这说明exit函数会冲刷缓冲区

修改.c文件
在这里插入图片描述
在这里插入图片描述

结果:等待2秒后,不会打印”hello world” ,这说明_exit函数不会冲刷缓冲区

exit vs _exit:exit函数会冲刷缓冲区,而_exit不会。
这说明,我们所说的缓冲区不在OS内,即不是内核缓冲区。

理由:

  1. exit底层调用的就是_exit,因为杀掉进程本质就是释放进程对应的代码和数据,释放进程的除pcb以外的其它内核数据结构。总之,是对进程做管理的一种方式。但用户没有权利对操作系统内的字段做任何访问,包括终止一个进程。因此,exit底层一定会调用_exit系统调用

在这里插入图片描述

如果缓冲区在操作系统,exit能冲刷缓冲区,那么_exit也能,因为exit底层调用的就是_exit。但是_exit不能,因此缓冲区不在OS内,即不是内核缓冲区,而在_exit之上,exit先冲刷缓冲区,再调用_exit


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

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

相关文章

python Tk 获取输入框内容,分割内容

创建输入框、一个按钮和一个标签的GUI。 用户可以在输入框中输入文本,点击按钮后,程序将在控制台打印输入的文本(已经分割为列表),并在GUI中的标签上显示一些静态文本。 import tkinter as tk# 创建主窗口 root tk.…

Win11可以安装AutoCAD2007

1、在win11中,安装AutoCAD2007,需要先安装NET组件。否则会提示缺少".net文件" 打开“控制面板”,点击“程序”,点击“程序和功能”,点击“启用或关闭Windows功能”,勾选“.NET FrameWork 3.5”&a…

【个人博客搭建练手版】Windows环境下使用tale,mblog,halo三种框架搭建个人博客,适合准备搭建博客的练手之作

昨天发了一篇搭建博客的教程,竟然上新人榜了。 博客链接:https://editor.csdn.net/md/?articleId139392436 趁热打铁把该文章中说的使用在Windows环境使用docker desktop搭建halo博客练手的教程也写一下。 这篇文章不只有halo的搭建,还有ta…

leetcode 所有可能的路径(图的遍历)

leetcode 链接: 所有可能的路径 1 图的基本概念 1.1 有向图和无向图 左边是有向图,右边是无向图。对于无向图来说,图中的边没有方向,两个节点之间只可能存在一条边,比如 0 和 1 之间的边,因为是无向图&am…

通过网址下载静态网页的仿站工具

下载地址:通过网址下载静态网页的仿站工具 超级实用的一款工具

TCP 建链(三次握手)和断链(四次握手)

TCP 建链(三次握手)和断链(四次挥手) 背景简介建链(三次握手)断链(四次挥手)序号及标志位延伸问题为什么建立连接需要握手三次,两次行不行?三次握手可以携带数…

使用GPT-soVITS再4060下2小时训练声音模型以及处理断句带来的声音模糊问题

B站UP主视频 感谢UP主“白菜工厂1145号员工”的“熟肉”,我这篇笔记就不展示整一个训练和推理流程,重点写的4060该注意的一些事项。如何解决断句模糊的问题,在本篇笔记的最末尾。 相关连接: 原项目github UP主的说明文档 1、训…

Java Web学习笔记21——前后端分离开发

前后端混合开发: 沟通成本比较高。 分工不明确。 不便管理,不便于后期的维护和拓展。 前后端分离开发: 当前主流的开发模式:前后端分离开发: 接口文档: 接口并不是interface。 接口指的是业务功能。 …

【c语言】qsort函数及泛型冒泡排序的模拟实现

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C语言 目录 一、qsort函数 1.回调函数 2.qsort函数 3.void* 指针 二、泛型冒泡排序的模拟实现 1.比较函数的编写 2.交换函数的编写 3.冒泡排序的编写 4…

这家叉车AGV巨头2024年一季度销售4075万~

导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》人俱乐部 一、BALYO公司概览 BALYO,这家来自法国的仓储机器人公司,自2006年成立以来,一直致力于为全球客户提供…

佳禾食品入手逻辑

佳禾食品 公司名称:佳禾食品工业股份有限公司 A股简称:佳禾食品 成立日期:2001-05-15 上市日期:2021-04-30 所属行业:食品制造业 否 主营业务:植脂末、咖啡及其他固体饮料等产品的研发、生产和销售。 产品类…

LLVM Cpu0 新后端7 第一部分 DAG调试 dot文件 Machine Pass

想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章: LLVM 后端实践笔记 代码在这里(还没来得及准备,先用网盘暂存一下): 链接: https://pan.baidu.com/s/1V_tZkt9uvxo5bnUufhMQ_Q?…

MySQL—多表查询—联合查询

一、引言 之前学习了连接查询。现在学习联合查询。 union:联合、联盟 对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集 涉及到两个关键字:union 和 union all 注意: union 会把上面两个SQL查询…

ACDSee Photo Studio Ultimate v17 解锁版安装教程 (图片编辑器)

前言 ACDSee Photo Studio Ultimate 2024,一款适合各类摄影师和创意人士的综合解决方案,具备了经过省时的本地人工智能 (AI) 强化的全新特性和改进功能,使您能够以最小的投入获得最大的控制,从而更轻松地管理、检索和编辑您的照片…

【Python】数据处理:OS目录文件操作

Python的os模块是一个用于与操作系统进行交互的标准库模块。它提供了丰富的功能来处理文件和目录、执行系统命令、获取和设置环境变量等。 工作目录操作 获取当前工作目录 os.getcwd()参数:无返回值:一个字符串,表示当前工作目录的路径。这…

微信小程序学习笔记(4)

文章目录 1、< template >< / template >2、样式导入i、wxmlii、wxss 3、flex布局i、容器属性ii、项目属性 1、< template >< / template > 模板可以重复调用 首先要定义一个模板&#xff1a; <template name"test"><view>{{…

OpenCV 双目相机标定

文章目录 一、简介1.1单目相机标定1.2双目相机标定二、实现代码三、实现效果参考资料一、简介 1.1单目相机标定 与单目相机标定类似,双目标定的目的也是要找到从世界坐标转换为图像坐标所用到的投影P矩阵各个系数(即相机的内参与外参)。具体过程如下所述: 1、首先我们需要…

基础数据结构 -- 队列

1. 简介 Java中的数据结构队列&#xff08;Queue&#xff09;是一种线性表&#xff0c;其特殊之处在于它只允许在表的后端进行插入操作&#xff0c;在表的前端进行删除操作。这种先进先出&#xff08;FIFO&#xff0c;First In First Out&#xff09;的结构类似于现实生活中的排…

线性回归例子, 学习笔记[机械学习]

参考书籍, [pythonによる機械学習入門] y ax b # 直线的线性回归 import numpy as np import matplotlib.pyplot as plt # 求最小二乘法的回归直线,用到的库 from sklearn import linear_model# x 和 y的单点图 x np.random.rand(100, 1) x x*4-2 y 3*x-2 # 增加一部分乱…

Django路由与会话深度探索:静态、动态路由分发,以及Cookie与Session的奥秘

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…