【Linux】进程控制(创建、终止、等待、替换)

文章目录

  • 1. 进程创建
  • 2. 进程终止
  • 3. 进程等待
  • 4. 进程程序替换
    • 4.1 认识进程替换
    • 4.2 认识全部接口

在这里插入图片描述

1. 进程创建

如何创建进程我们已经在之前学习过了,无非就是使用fork(),它有两个返回值。创建成功,给父进程返回PID,给子进程返回0;创建失败,给父进程返回-1。

由于虚拟地址空间的存在,父子两进程各自独立,父子代码共享,父子在不修改时,数据也是共享的;当将fork的返回值进行写入时,便以写时拷贝的方式各自一份副本。具体见下图:
在这里插入图片描述
但是操作系统怎么知道要发生写时拷贝呢?

在调用fork时,父进程会先将页表中的执行权限全部改成只读。那么子进程继承下来的页表项,全部都是只读的。

当通过代码区对某些数据段就行写入时,会被页表识别到,并触发系统错误(缺页中断);只不过触发错误的时候,系统会判断是真的发生了错误,还是要发生写时拷贝!

fork常规用法

  • 一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子 进程来处理请求。
  • 一个进程要执行一个不同的程序。例如子进程从fork返回后,调用execl函数,来执行不同的程序。(进程程序替换)

2. 进程终止

在我们以前写程序的时候,main函数总是会带一个返回值,但这个返回值有什么用处呢?它是给谁看的呢?- - 返回给父进程(bash)或者系统。

在下面的程序中,main函数返回了0

在这里插入图片描述

这个退出码有什么用呢? - - 表明错误的原因,一般用0表示成功,非0表示错误。

C/C++给我们提供了一些错误码,errno,perror,strerror等函数。

在这里插入图片描述

将退出码返回以后,可以供父进程或操作系统获得错误信息,所以这个错误码是给机器看的。

不同的系统,提供的错误码的种类和数量可能不同的;同时你也可以自己定义退出码。

进程终止的方式:

  1. mian函数 return 返回
  2. exit(),会刷新缓冲区,底层调用_exit()
  3. _exit(),不会刷新缓冲区,是一个系统调用接口
  • return vs exit()

在这里插入图片描述

  • exit vs _exit

在这里插入图片描述

3. 进程等待

在进程状态那里讲过,子进程退出,如果父进程不读取它,它会变成僵尸进程。
在这里插入图片描述
为了避免子进程进入僵尸状态,父进程该如何读取子进程,回收它呢?- - -使用wait方法。

在这里插入图片描述

一般而言,父进程创建了子进程,就要对子进程负责,就要等待子进程,直到子进程结束。如果子进程不退出,父进程就要阻塞在wait函数内部。

在这里插入图片描述
除了回收子进程外,父进程还需要知道子进程把任务完成的怎么样呢? - -使用waitpid()

pid_t waitpid(pid_t pid, int *status, int options);
  • waitpid的第一个参数pid

pid > 0:等待指定的子进程
pid == -1:等待任意一个子进程

在这里插入图片描述

那如何获得子进程的退出信息呢?

  • waitpid的第二个参数 status

在这里插入图片描述

子进程的退出码,是通过我们所传递的第二个参数带出来的,理想结果应该就是子进程的退出码1。
但是实际结果为什么是256呢?

在这里插入图片描述

这是因为status中不仅仅包含进程退出码,它还包括一些退出信息。
status不能简单的当作整形来看待,可以当作位图来看待,它有32个比特位,具体细节如下图(只研究status低16个比特位)
在这里插入图片描述

它的次低八位才是退出码

在这里插入图片描述

那低八位上的退出信号是干什么用的呢?

我们知道,进程退出有三次原因

  1. 代码跑完,结果对,return 0
  2. 代码跑完,结果错误,return 非0
  3. 进程异常

对于前两种原因,我们都可以通过退出码来识别错误;
对于第三种原因,进程异常直接会被操作系统使用信号终止,但是退出码是进程正常终止时由进程本身设置的,用于向父进程报告其结束状态或结果。然而,当进程因为接收到一个信号(如段错误、非法指令、用户中断等)而异常终止时,退出码就不再是一个可靠的指示器了。

所以,低七位上的会记录退出信号,第7位有其它作用,信号如下:

在这里插入图片描述
我们发现没有0号信号,因为0号信号标记着进程正常退出。

在这里插入图片描述

所以,当一个进程结束时,如果退出信号为0,则表示正常退出;但结果对不对,我们还需要再通过退出码来判断。

除了使用位运算来获取进程的退出信息,系统还提供了两个宏供我们使用:

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

在这里插入图片描述

  • waitpid的第三个参数option

options = 0 : 阻塞等待
options = WNOHANG:非阻塞等待。需要由你自己循环调用非阻塞接口,完成轮循检测,可以让调用方在轮循检测期间做更多自己的事情。

在这里插入图片描述

当option被设置为WNOHANG时,则函数有三个返回值:

  1. 返回值 > 0 : 非阻塞等待成功,返回子进程的PID
  2. 返回值 < 0 :非阻塞等待失败
  3. 返回值 = 0 :等待的进程尚未退出

所以,当函数的返回值 = 0时,可以让父进程执行一些其它的任务,然后轮循检测子进程是否退出。
在这里插入图片描述

4. 进程程序替换

4.1 认识进程替换

以往我们所创建出来的子进程,都是在执行和父进程相关的程序,那我能不能让子进程去执行一个全新的程序呢?下面展示的接口就是来完成程序替换的·

在这里插入图片描述
见一见进程替换

在这里插入图片描述

运行我们自己的程序发现,它去调用了系统的ls命令。也就是你main函数中没有代码,但是你去调用了人家ls的代码,这就是进程替换。

进程替换不是创建新的进程,仅仅是将代码和数据替换、页表映射修改一下,进程相关的PCB信息根本没有变化。

  • 参数

那这个execl函数的参数都是什么意思呢?
在这里插入图片描述
简而言之,path就是你要执行谁,后面的可变参数列表就是你想怎么执行它。

  • 返回值

这个execl的返回值是干什么用的呢?

在这里插入图片描述
只有调用execl时发生错误,该函数才会后返回-1;成功时没有返回值,因为调用成功后代码全被覆盖了,那它返回什么,所以只要它返回,它必定是失败的。

有了上面的理解后,我们做个简单的总结:

  1. 在进程替换的使用中,一般不会让当前进程去替换,而是创建一个子进程去替换。父进程只需看子进程表演,如果想获得子进程任务的执行情况,通过返回码判断。如果返回了,则替换失败;没有返回,替换成功。
    在这里插入图片描述
  2. 如果我不再将execl的参数写死,而是让用户输入,并且我给这段代码在套一个死循环,这不就是一个简单的命令行解释器吗?
  3. 在linux中,所有的进程都是由父进程创建的,那系统是怎么把我们的程序跑起来的呢?也无非就是先fork,然后进行程序替换。
  4. 所以进程创建时要先有内核数据结构,即:使用fork继承父进程的;然后再execl加载自己的代码和数据,这不就是一个新的程序了吗?
  5. 因此,用户所执行的所有程序,在操作系统看来全部都是进程。无非就是fork以后再执行程序替换

4.2 认识全部接口

进程替换一共有7个接口
在这里插入图片描述

第七个execve是系统调用,前6个都是C帮我们封装的函数,底层是调用的第七个。

  • execv vs execl

二者的区别就是execv将后面的参数,全部放在了一个vector里;execl是放在了一个list中

在这里插入图片描述
此时的vector数组,是不是就像main函数的命令行参数呢? - -就是这样,系统就是通过这个传递给main函数的。

execl函数内部也会将所传递的参数转化为上图所示的数组!

  • execlp vs execvp

在这里插入图片描述
带p(path)意味着:调用时无需指定路径,只需指定调用谁。v和l的区别还是vector与list

在这里插入图片描述

为什么不需要指定路径了呢?因为它会自己去path路径下找。

  • execvpe

在这里插入图片描述

除了告诉系统我要执行谁,怎么执行,我还可以给它传递新的环境变量,此时第三个参数就是环境变量。

当我们不传递时,替换的程序可以获得环境变量吗?- - 可以,通过全局指针变量envrion。
当我们传了,此时就会用我们所传递的,替换环境变量,程序使用全新的环境变量。
在这里插入图片描述

在这里插入图片描述

但是我不想改变整个环境变量表,仅仅想增加环境变量呢?

putenv()谁调用该函数,就将新的环境变量添加到它环境变量表当中!
如子进程添加环境变量,父进程的不变。
在这里插入图片描述

这些函数原型看起来很容易混,但只要掌握了规律就很好记。

  • l(list) : 表示参数采用列表
  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量

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

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

相关文章

解决:使用layui.treeTable.updateNode,更新表格数据后,done里面的事件丢失问题

1. 背景 在给树形表格添加行点击事件&#xff0c;并且只更新当前行数据。 treeTable.updateNode("SpeProjListId", result.LAY_DATA_INDEX, result);更新数据后&#xff0c;点击事件失效。 1. 给字段绑定事件&#xff1a; class"link_a link_style" , {…

AI2.0时代,普通小白如何通过AI月入30万

最近这2年AI真的太火了&#xff0c;很多人都在讨论怎么用AI赚钱、提高效率。其实&#xff0c;我觉得AI并没有那么复杂&#xff0c;尤其是如果你不做AI底层研究&#xff0c;只是利用它来帮你省事、提效、赚钱&#xff0c;那就像当初学用电脑、用手机一样简单。你不需要懂AI的技术…

论文阅读:PET/CT Cross-modal medical image fusion of lung tumors based on DCIF-GAN

摘要 背景&#xff1a; 基于GAN的融合方法存在训练不稳定&#xff0c;提取图像的局部和全局上下文语义信息能力不足&#xff0c;交互融合程度不够等问题 贡献&#xff1a; 提出双耦合交互式融合GAN&#xff08;Dual-Coupled Interactive Fusion GAN&#xff0c;DCIF-GAN&…

Oracle 数据库安装和配置详解

Oracle 数据库安装和配置详解 Oracle 数据库是一款功能强大、广泛使用的企业级关系数据库管理系统 (RDBMS)&#xff0c;适用于处理大型数据库和复杂事务。本文将介绍如何在 Linux 和 Windows 环境下安装 Oracle 数据库&#xff0c;并对其进行基本配置&#xff0c;帮助开发者快…

国外电商系统开发-运维系统拓扑布局

点击列表中设备字段&#xff0c;然后定位到【拓扑布局】中&#xff0c;可以看到拓扑发生了变化 再回头&#xff0c;您再次添加一个服务器到系统中&#xff0c;并且选择该服务器的连接节点为您刚才创建的“SDN路由器”&#xff0c;保存后&#xff0c;您可以看到这个服务器连接着…

红帽操作系统Linux基本命令2( Linux 网络操作系统 06)

本文接着上篇Linux常用命令-1继续往后学习其他常用命令。 2.3 目录操作类命令 1&#xff0e;mkdir命令 mkdir命令用于创建一个目录。该命令的语法为&#xff1a; 上述目录名可以为相对路径&#xff0c;也可以为绝对路径。 mkdir命令的常用参数选项如下。 -p&#xff1a;在创…

通过dem2terrain生成MapboxGL地形服务

概述 MapboxGL在2的版本之后通过地形服务开始支持三维的展示了&#xff0c;之前也有文章“mapboxGL2中Terrain的离线化应用”对该服务进行过说明与分析。前些天在翻公众号的时候翻到了dem2terrain可以生成地形服务&#xff0c;同时做了一些优化&#xff0c;今天就给大家分享一…

畅享免费服务:PDF 转图片在线转换软件的魅力

为了方便在社交媒体上分享文档内容&#xff0c;还为了更好地适应特定的编辑需求&#xff0c;将 PDF 文件转换为图片格式都具有重要的意义。而如今&#xff0c;幸运的是&#xff0c;有许多pdf转图片在线转换免费工具为我们提供了便捷、高效的 PDF 转图片服务。接下来&#xff0c…

MongoDB 数据库服务搭建(单机)

下载地址 下载测试数据 作者&#xff1a;程序那点事儿 日期&#xff1a;2023/02/15 02:16 进入下载页&#xff0c;选择版本后&#xff0c;右键Download复制连接地址 下载安装包 ​ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.14.tgz​ …

Redis: Sentinel哨兵监控架构及环境搭建

概述 在主从模式下&#xff0c;我们通过从节点只读模式提高了系统的并发能力并发不断增加&#xff0c;只需要扩展从节点即可&#xff0c;只要主从服务器之间&#xff0c;网络连接正常主服务器就会将写入自己的数据同步更新给从服务器&#xff0c;从而保证主从服务器的数据相同…

SQL自用小结

推荐一下这个知识点总结 《数据库系统概论》第五版 学习笔记总目录 1. SQL概述 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是一种用于定义、查询、更新和控制关系数据库的标准化语言。 它包含了数据定义语言&#xff08;DDL&#xff0…

51单片机系列-按键检测原理

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 独立按键是检测低电平的。 下面我们来看一张对应的电路原理图&#xff1a; 在这张图当中&#xff0c;P1&#xff0c;P2&#xff0c;P3内部都上拉了电阻&#xff0c;但是P0没有&am…

码随想录算法训练营第62天|卡码网:97. 小明逛公园、127. 骑士的攻击

1. 卡码网 97. 小明逛公园 题目链接&#xff1a;https://kamacoder.com/problempage.php?pid1155 文章链接&#xff1a;https://www.programmercarl.com/kamacoder/0097.小明逛公园.html 思路&#xff1a; 使用Floyd 算法&#xff0c;目的是解决多源最短路问题&#xff0c;即 …

Java项目实战II基于Java+Spring Boot+MySQL的房产销售系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 随着房地产市场的蓬勃发展&#xff0c;房产销售业务日益复杂&#xff0c;传统的手工管理方式已难以满…

机器学习/数据分析--用通俗语言讲解时间序列自回归(AR)模型,并用其预测天气,拟合度98%+

时间序列在回归预测的领域的重要性&#xff0c;不言而喻&#xff0c;在数学建模中使用及其频繁&#xff0c;但是你真的了解ARIMA、AR、MA么&#xff1f;ACF图你会看么&#xff1f;&#xff1f; 时间序列数据如何构造&#xff1f;&#xff1f;&#xff1f;&#xff0c;我打过不少…

EEPROM读写实验——FPGA学习笔记18

一、EEPROM简介 Electrically Erasable Progammable Read Only Memory:是指带电可擦可编程只读存储器&#xff0c;是一种常用的非易失性存储器&#xff08;掉电数据不丢失&#xff09; EEPROM发展历史 我们这次实验所用的AT24C64存储容量为64Kbit&#xff0c;内部分成256页&am…

Java--IO高级流

缓冲流 缓冲流,也叫高效流&#xff0c;是对4个基本的FileXxx 流的增强&#xff0c;所以也是4个流&#xff0c;按照数据类型分类&#xff1a; 字节缓冲流&#xff1a;BufferedInputStream&#xff0c;BufferedOutputStream 字符缓冲流&#xff1a;BufferedReader&#xff0c;Buf…

【2024】uniapp 接入声网音频RTC【H5+Android】Unibest模板下Vue3+Typescript

需求 最近开发一个项目&#xff0c;需要实现声网的接入。由于采用uniapp模式&#xff0c;按照最佳实践采用优先开发H5再适配的模式。因此实现了H5和Android两种模式的接入&#xff0c;Android里采用离线打包自定义基座来进行调试。怕自己忘记了&#xff0c;在这里详细的记录完…

Hadoop之WordCount测试

1、Hadoop简介&#xff1a; Hadoop是Apache旗下的一个用Java语言实现的开源软件框架&#xff0c;是一个开发和运行处理大规模数据的软件平台。 Hadoop的核心组件包括Hadoop分布式文件系统&#xff08;HDFS&#xff09;和MapReduce编程模型。HDFS是一个高度容错的系统&#xf…

OpenGL笔记十九之相机系统

OpenGL笔记十九之相机系统 —— 2024-10-02 晚上 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记十九之相机系统1.运行1.1.游戏相机1.2.轨迹球相机 2.游戏相机与轨迹球相机切换3.博主笔记本要运行需要更改的文件更改1:28_OpenGL_CameraSystem/applicat…