【Linux杂货铺】进程控制


目录

🌈前言🌈

📁 进程创建

📂 fork函数

📂 写实拷贝

📂 创建进程的目的

📂 创建失败原因

📁 进程终止

📂 概念

📂 场景

📂 退出方法

📁 进程等待

📂 概念

📂等待方式

📁 进程替换

📂 原理

📂 替换函数

📂 命名解释 

📁 总结


🌈前言🌈

        欢迎收看本期【Linux杂货铺】,本期内容将讲解Linux中如何管理控制进程,包含了创建进程,进程终止,等待进程,进程替换等内容,期间会拓展讲解写实拷贝,系统调用接口的使用等内容。

📁 进程创建

📂 fork函数

        在Linux中fork函数是非常重要的函数,是用来在已有的进程中创建一个新的进程。新进程为子进程,原有进程为父进程。

#include <unistd.h>

pid_t fork(void);

返回值: 有两个返回值,对于父进程返回子进程的pid,子进程返回0,出错返回-1

进程调用fork函数,内核做:

1. 分配新的内存块和内存数据结构给子进程。

2. 将父进程部分数据结构拷贝到子进程。

3. 添加子进程到系统进程列表中。

4. fork返回,开始调度器调度。

📂 写实拷贝

        通常,父子进程代码共享,父子不在写入时,数据也是共享的即指向同一块内存块。当任意一方进行写入时,会创建新的内存块,不在指向同一块内存块。

        因为有页表的存在,所以在上层,看见的虚拟地址是不变的,但实际的物理地址却不同。

        在C/C++中,我们看到的地址都是虚拟地址,不是实际的物理内存地址,通过页表的映射,来操作物理地址上的数据。

        所以,写实拷贝就是,当共享代码和数据的父子进程,任意一方修改数据时,会创建新的物理内存,改变虚拟地址与物理地址的映射,虚拟地址不变。

📂 创建进程的目的

        1. 父进程希望复制自己,使父子进程执行不同的代码段。(通过if 判断来执行不同的代码)

        2. 一个进程要执行一个不同的程序。(进程替换)

📂 创建失败原因

        1. 系统有太多的进程。

        2. 实际用户的进程数超过了限制。

📁 进程终止

📂 概念

        1. 释放代码和数据占用的空间。

        2. 释放内核数据结构(页表,地址空间),但是PCB延迟处理,并将进程进程设为Z(僵尸状态),等待父进程处理。

📂 场景

1. 程序运行完毕,结果正确。

2. 程序运行完毕,结果不正确。(退出码)

        进程想要告诉父进程运行完毕,结果是否正确。怎么告诉呢,就有了退出码的概念。退出码的作用,就是告诉父进程,子进程退出情况是成功,还是失败,如果失败,失败原因是什么。

3. 程序异常终止。(退出信号)

        异常终止的概念是,操作系统发现了进程做了不该做的事,例如野指针的使用等。本质是操作系统向进程发送信号,杀掉进程,此时,退出码没有意义

📂 退出方法

        1. main函数中,直接return。

        2. exit() : 库函数,会刷新缓冲区,封装了_exit()。        

        3. _exit():系统调用接口,不会刷新缓冲区。

📁 进程等待

📂 概念

        子进程退出时,父进程如果不进行处理,就会造成"僵尸问题",即子进程无法被杀死,一直存在,进而造成内存泄漏。

        所以,父进程通过进程等待的方式,回收子进程资源,获取子进程的退出信息。

📂等待方式

        这里介绍的是第三种方式,waitpid方式,这三个参数分别是什么意思。

返回值:

        > 0 : 正常的返回时,waitpid返回收集到的子进程的进程id。

        == 0 : 非阻塞等待,设置了WNOHNAG,waitpid发现没有退出的子进程可收集。

        < 0 : 调用中出错,返回-1,error会被设置成相应的值以指示错误所在。例如参数给出错误的pid。

1. pid:

pid = -1,等待任意一个子进程,与wait等效。

pid > 0 ,等待进程pid与参数pid相等的子进程。

2. status:

        如果想要查看进程的退出码和退出信号,可以传递一个int类型的数据,返回时,通过操作status来查看退出码和退出信息。

        status参数是通过位图来操作的,最低的8位是终止信号;此地八位是退出码,通过&操作,来实现查看退出信息。

        标准提供了宏函数,帮助查看进程是否是正常终止,以及退出码。

WIFEXITED(status) : 若正常终止子进程,返回值为真 >0。

WEXITSTATUS(status):拓WIFEXITED非0,提取子进程退出码。

3.options:

        进程等待分为阻塞等待 和 非阻塞等待。两者的区别在于进程是否可以做其他的事情。

        例如,张三给李四打电话,李四说马上下来,张三就一直拿着电话,问好了吗,这就是阻塞等待。而如果张三打完电话,就打游戏,刷会视频,过了会再打一次电话,一直到李四下来,这就是非阻塞等待。

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

        所以,非阻塞等待 + 循环 就是实现了非阻塞轮询,就是打完电话,没下来就玩游戏,打完游戏,再打一次电话,循环往复。

📁 进程替换

📂 原理

        用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一个exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间和代码和数据完全被新进程替换,从新进程的启动例程开始执行,

        调用exec函数并不创建新进程,所以调用exec前后该进程id不变。

        通过下图,可知,将替换进程数据覆盖到原有进程的物理内存中,此后,进程的数据就变为了替换进程的数据。

📂 替换函数

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

        函数调用成功则会加载新的程序到启动代码处,开始执行,不在返回。调用出错返回-1.所以exec* 函数只有出错有返回值,没有成功的返回值。

        其中execve是系统调用接口,其他的则是库函数。

#include <unistd.h>
int main()
{
 char *const argv[] = {"ps", "-ef", NULL};
char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};
 execl("/bin/ps", "ps", "-ef", NULL);
 // 带p的,可以使用环境变量PATH,无需写全路径
 execlp("ps", "ps", "-ef", NULL);
 // 带e的,需要自己组装环境变量
 execle("ps", "ps", "-ef", NULL, envp);
 execv("/bin/ps", argv);
 
 // 带p的,可以使用环境变量PATH,无需写全路径
 execvp("ps", argv);
 // 带e的,需要自己组装环境变量
 execve("/bin/ps", argv, envp);
 exit(0);
}

📂 命名解释 

l ( list ): 表示参数采用列表。

v ( vector ) : 参数用数组。

p (path) : 有p自动搜索环境变量PATH。

e (env) : 表示自己维护环境变量。

📁 总结

        以上,就是本期【Linux杂货铺】的主要内容了,其中介绍了如何创建进程;进程终止的三种场景,了解退出码和退出信号的概念;最后介绍了进程替换的概念,如何实现进程替换等内容。

        如果,感觉本期内容对你有帮助,欢迎点赞,关注,评论。Thanks♪(・ω・)ノ

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

欧几里得算法-----无聊的军官pro max版本

上篇文章末尾我们说学了欧几里得算法一定给大家更新。 今天它来了&#xff01; 欧几里得算法 欧几里得算法是一种求最小公倍数和最大公因数的算法。 我们看图&#xff1a; 我们把两个数看成长方形&#xff0c;在长方形内不断划分出小正方形&#xff0c;PS&#xff1a;第一个…

一图理解递归-算法通关村

一图理解递归-算法通关村 递归是我们算法进阶的基础&#xff0c;是必须要掌握的内容&#xff0c;只有掌握了递归才算真的会算法。与递归有关的问题有&#xff1a; 与树和二叉树相关的大部问题二分查找相关的问题快速排序、归并排序相关的问题所有回溯的问题所有动态规划的问题 …

scrapy爬虫框架

scrapy爬虫框架 一、scrapy的概念作用和工作流程1、scrapy的概念2、scrapy框架的作用3、scrapy的工作流程&#xff08;重点&#xff09;3.1 回顾之前的爬虫流程3.2 改写上述流程3.3 scrapy的流程3.4 scrapy的三个内置对象3.5 scrapy中每个模块的具体作用 二、scrapy的入门使用1…

【机器学习】无监督学习算法之:主成分分析

主成分分析 1、引言2、主成分分析2.1 定义2.2 原理2.3 实现方式2.4 算法公式2.5 代码示例 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c; 快&#xff0c;快。 小鱼&#xff1a;… 啥情况&#xff0c; 你可别乱喊。 小屌丝&#xff1a;额… 我的意思&#xff0c;是你该继…

【附订阅OnlyFans攻略】2024年AI:一个交织着创新与挑战的故事

2024年AI&#xff1a;一个交织着创新与挑战的故事 在2024年的一个清晨&#xff0c;阳光透过智能窗户的调节&#xff0c;柔和地洒在书房里。李华&#xff0c;一位年轻的科技创业者&#xff0c;坐在书桌前&#xff0c;凝视着电脑屏幕上不断跳动的数据和图像。他正在进行一项重要…

Flutter 项目架构技术指南

Flutter 项目架构技术指南 视频 https://www.bilibili.com/video/BV1rx4y127kN/ 前言 原文 https://ducafecat.com/blog/flutter-clean-architecture-guide 探讨Flutter项目代码组织架构的关键方面和建议。了解设计原则SOLID、Clean Architecture&#xff0c;以及架构模式MVC…

qt 实现 轮播图效果,且还有 手动 上一页和下一页 已解决

QT中有 轮播图的需求&#xff0c;按照正常html版本 。只需要配置数组就能搞定&#xff0c;但是c qt版本 应该用什么了。 第一想到的是采用定时器。 // 定时器初始化{m_pTime new QTimer(this);m_pTime->start(4 * 1000);//启动定时器并设置播放时间间隔m_pAutoFlag true;/…

网络层(IP层)

IP协议的本质&#xff1a;有将数据跨网络传输的能力 而用户需要的是将数据从主机A到主机B可靠地跨网络传输 IP的组成&#xff1a;目标网络目标主机 IP由目标网络和目标主机两部分组成&#xff0c;IP报文要进行传输&#xff0c;要先到达目标网络&#xff0c;然后经过路由器转到…

使用阿里云服务器搭建网站教程,超简单10分钟网站上线

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…

【算法设计与分析】实现Trie前缀树

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 Trie&#xff08;发音类似 "try"&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串…

【评分标准】【网络系统管理】2019年全国职业技能大赛高职组计算机网络应用赛项H卷 无线网络勘测设计

第一部分&#xff1a;无线网络勘测设计评分标准 序号评分项评分细项评分点说明评分方式分值1点位设计图AP编号AP编号符合“AP型号位置编号”完全匹配5AP型号独立办公室、小型会议室选用WALL AP110完全匹配5员工寝室选用智分&#xff0c;其他用放装完全匹配5其它区域选用放装AP…

睿考网:二建可以跨省考试吗?

二级建造师资格考试允许考生进行跨省报名&#xff0c;但是考试通过后的注册环节&#xff0c;必须在考试所在的省份完成。建议在初始注册过程中选择与报名信息相符的单位&#xff0c;以确保符合当地的职业要求规定。 关于二建的考试地点&#xff0c;考生可以选择在工作单位所在…

鸿蒙Harmony应用开发—ArkTS-@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化

上文所述的装饰器仅能观察到第一层的变化&#xff0c;但是在实际应用开发中&#xff0c;应用会根据开发需要&#xff0c;封装自己的数据模型。对于多层嵌套的情况&#xff0c;比如二维数组&#xff0c;或者数组项class&#xff0c;或者class的属性是class&#xff0c;他们的第二…

sr501人体红外传感器

sr501人体红外传感器 文章目录 sr501人体红外传感器1.介绍2.使用方法3.示例代码 持续更新中1.介绍 模块信息介绍来自百问网&#xff0c;仅供学习和参考​ 人体都有恒定的体温&#xff0c;一般在 37 度&#xff0c;所以会发出特定波长 10uM 左右的红外线&#xff0c;被动式红外…

推荐一款制造执行系统(MES)国内比较好的实施厂家

什么是MES 制造执行系统&#xff08;MES&#xff09;是一种用于监控、控制和优化制造过程的软件系统。它通过与企业资源计划&#xff08;ERP&#xff09;系统和自动化系统的集成&#xff0c;实现对生产过程的管理和监测&#xff0c;包括生产计划、生产过程和生产数据。 MES可…

基于python+vue分类信息服务平台移动端的设计与实现flask-django-php-nodejs

分类信息服务平台是在Android操作系统下的应用平台。为防止出现兼容性及稳定性问题&#xff0c;框架选择的是django&#xff0c;Android与后台服务端之间的数据存储主要通过MySQL。用户在使用应用时产生的数据通过 python等语言传递给数据库。通过此方式促进分类信息服务平台信…

高等数学基础篇(数二)之微分方程

微分方程&#xff1a; 一、常微分方程的基本概念 二、一阶微分方程 三、可降阶的高阶方程 四、高阶线性微分方程 目录 一、常微分方程的基本概念 二、一阶微分方程 三、可降阶的高阶方程 四、高阶线性微分方程 一、常微分方程的基本概念 二、一阶微分方程 帮助理解&…

C++学习之旅(二)运行四个小项目 (Ubuntu使用Vscode)

如果是c语言学的比较好的同学 可以直接跟着代码敲一遍&#xff0c;代码附有详细语法介绍&#xff0c;不可错过 一&#xff0c;猜数字游戏 #include <iostream> #include <cstdlib> #include <ctime>int main() {srand(static_cast<unsigned int>(tim…

SpringBoot整合Swagger-UI实现在线API文档

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:SpringBoot整合Swagger-UI实现在线API文档 📚个人知识库: Leo知识库,欢迎大…

在 vite 开发环境,使用https自签证书 --- mkcert

在 vite 开发环境&#xff0c;使用https自签证书 — mkcert 使用basicSsl&#xff08;vitejs/plugin-basic-ssl&#xff09; 在vite开发环境中&#xff0c;使用 basicSsl 插件能暂时提供https服务&#xff0c;同时&#xff0c;也会面临总是提示一下的问题,如下图 提示https证…