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

Linux第四节:进程控制


一、进程创建

1.1 fork函数

1. fork函数有两个返回值问题
返回的本质就是写入!所以,谁先返回,谁就先写入id,因为进程具有独立性,会发生写时拷贝,父进程和子进程各自指向return语句。

2. fork返回后,给父进程返回子进程pid,给子进程返回0
一个子进程有且仅有一个父进程,使用子进程找到父进程很简单;但是使用父进程找子进程很麻烦,必须要有子进程相关的数据。

3. 同一个id值,会保存两个不同的值,同时让ifelse if 执行
fork函数中,当子(父)进程尝试写入数据,操作系统会进行数据拷贝到新的区域、更改该区域对应页表、再让进程修改数据,为了保证进程的独立性。这时就会出现对同一个变量的同一个虚拟地址,会有两个不同输出值。(写时拷贝)

所以,调用fork函数之前,父进程独立执行;调用fork之后,父子两个执行流分别执行。 fork 之后,谁先执行,完全由调度器决定。


1.2 写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。如下图:
在这里插入图片描述
在这个过程中,子进程改变没有影响父进程。写时拷贝:写的时候进行拷贝。
虚拟地址空间+页表 用于保证进程的独立性;一旦有执行流想要写入代码或数据,就会发生写实拷贝。


1.3 fork用法

  1. 父进程希望复制自己,使父子进程同时执行不同进程
  2. 一个进程要执行一个不同的程序。例如:子进程从fork 返回之后,调用 exec 函数。

1.4 fork调用失败

  1. 系统中有太多进程
  2. 达到实际用户的进程数超过了限制

二、进程终止

2.1 进程退出码

在自己写C/C++ 代码时,最后总是写一个 return 0 。在系统中,这个语句是:进程退出时,对应的退出码。用于标定进程执行的结果是否正确。

写代码是为了完成某件事,可是在代码执行结束后,我怎么知道代码跑的结果对不对呢?—进程退出码

./mytest # 运行一个进程 
echo $? # 永远记录最近一个进程在命令中执行完毕时对应的退出码(main->return ?;)

如果我们不关心进程退出码,直接return 0 就好了;如果关心进程退出码,就要返回特定数据表明特定错误。退出码的意义:0—成功; !0—表示失败
一般而言,退出码都有对应的文字描述。可以自定义,也可以使用系统的映射关系(不太频繁)


2.2 进程退出场景

进程退出一共只有三种

  1. 代码跑完了,结果正确—return 0
  2. 代码跑完了,结果不正确–return !0
  3. 代码没跑完,程序异常了,退出码无异意义

2.3 进程如何退出(结束)

  1. main 函数返回
  2. 任意地方调用 exit — 库函数;在进程终止之后会主动刷新缓冲区
  3. _exit 终止进程 — 系统调用;在进程终止之后不会刷新缓冲区

这里的缓冲区是指—用户级缓冲区(基础IO细讲)
在这里插入图片描述


三、进程等待

之前讲过,进程状态有一个 Z状态 —会造成进程泄露;我们通过进程等待解决僵尸进程问题。

3.1 进程等待的方法

  1. wiait 方法
    #include<sys/types.h>
    #include<sys/wait.h> pid_t wait(int*status);
  • 返回值:成功—返回被等待进程pid;失败—返回 -1;
  • 参数:输出型参数,获取子进程退出状态,不关心则可以设置为 NULL。
  1. waitpid 方法
    bash pid_ t waitpid(pid_t pid, int *status, int options);
  • 返回值:
    • 当正常返回的时候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。

3.2 再谈进程退出

  1. 进程退出,该进程会变成僵尸程序------会把自己的退出结果写入到自己的 task_struct
  2. wait/waitpid 是一个系统调用 —>OS—>OS有资格也有能力去读取子进程的 task_struct
  3. 所以退出结果是操作系统从 task_struct 中读取到的。

3.3 非阻塞式等待

  1. WNOHANG 非阻塞---->子进程没有退出,父进程检测后立即返回,继续自己的任务。
  2. waitpid 调用成功&&子进程没有退出:我的 waitpid 没有等待失败,仅仅是监测到了子进程没有退出,父进程立即返回。
  3. waitpid 调用成功&&子进程退出:父进程回收子进程。
  4. waitpid 调用失败:返回值为 -1。
  5. 非阻塞等待不会占用父进程所有时间,在轮询期间可以处理其他任务。

3.4 进程等待小结

  1. 是什么:通过系统调用,让父进程等待子进程的一种方式。
  2. 为什么:释放僵尸子进程、获取子进程状态 。
  3. 怎么办:使用 waitwaitpid 函数。

四、进程替换

(引子)创建子进程的目的是什么?

  1. 想让子进程执行父进程代码的一部分(执行父进程对应的磁盘代码中的部分)
  2. 想让子进程执行一个全新的程序(让子进程想办法,加载磁盘上指定的程序,执行新程序的代码和数据)
    我们把“加载磁盘上指定的程序,执行新程序的代码和数据”叫做进程的程序替换

4.1 替换原理

在这里插入图片描述

  1. 调用 exec 系列函数进行程序替换,本质就是讲指定程序的代码和数据加载到指定位置,覆盖自己的代码和数据。
  2. 程序替换没有创建新的进程。
  3. 在调用程序替换函数后,函数后续的代码就无法执行,被替换掉了。
  4. exec 系列函数没有调用成功的返回值,调用成功了就和接下来的代码没关系了(第三点),所以该函数调用后只要有返回,就一定是出错了。

4.2 替换函数

常用的以 exec 开头的函数:

#include <unistd.h>// l->list:将参数一个一个的传入exec*。
int execl(const char *path, const char *arg, ...); 
// p->path:如何找到程序的功能,带 p 字符的函数,不用告诉我程序的路径。
//你只要告诉我程序的名字,我自己会到系统中去找。
int execlp(const char *file, const char *arg, ...); 
int execle(const char *path, const char *arg, ...,char *const envp[]);// v->vector:可以将所有的执行参数,放入数组中,统一传递,而不用进行使用可变参数方案.
int execv(const char *path, char *const argv[]);
// e->envp:环境变量
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, const char *argv[], char *const envp[]);

在这里插入图片描述
在这里插入图片描述


4.3 试验

我们可以综合前面的知识,做一个简易的shell。
放在后面单独写一篇文章。

在这里插入图片描述

相关文章:

Linux第四节:进程控制

一、进程创建 1.1 fork函数 1. fork函数有两个返回值问题 返回的本质就是写入&#xff01;所以&#xff0c;谁先返回&#xff0c;谁就先写入id&#xff0c;因为进程具有独立性&#xff0c;会发生写时拷贝&#xff0c;父进程和子进程各自指向return语句。 2. fork返回后&#x…...

Qt 编译 sqldrivers之psql

编译postgres pgsql驱动 下载驱动源码修改配置文件编译 下载驱动源码 // 源代码下载 https://download.qt.io/archive/qt/5.15/5.15.2/submodules/驱动目录:qtbase-everywhere-src-5.15.2\src\plugins\sqldrivers 修改配置文件 打开pro文件 右键点击添加库 此处的为debu…...

382_C++_在用户会话结束时,检查是否有其他会话仍然来自同一个客户端 IP 地址,没有连接状态设置为断开,否则为连接

之前出现的问题:重启管理机,工作机上面热备连接状态显示未连接 (此时是有一个工作机连接管理机的),所以正常应该是连接状态解决:根因分析: 重启管理机后,管理机给过来的cookie是空的,导致工作机同时存在两个管理机的session,在其中一个超时后,调用回调函数通知会话断开…...

RViz(机器人可视化工具)的配置文件(moveitcpp)

1. Panels&#xff08;面板设置&#xff09; 面板是RViz界面中的各个功能区域&#xff0c;用于显示和操作不同的数据。 Displays&#xff08;显示面板&#xff09; Class: rviz_common/Displays 指定面板的类型&#xff0c;这里是显示面板。 Help Height: 78 帮助区域的高度…...

Redis中6种缓存更新策略

Redis作为一款高性能的内存数据库&#xff0c;已经成为缓存层的首选解决方案。然而&#xff0c;使用缓存时最大的挑战在于保证缓存数据与底层数据源的一致性。缓存更新策略直接影响系统的性能、可靠性和数据一致性&#xff0c;选择合适的策略至关重要。 本文将介绍Redis中6种缓…...

如何使用极狐GitLab 软件包仓库功能托管 terraform?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 Terraform 模块库 (BASIC ALL) 基础设施仓库和 Terraform 模块仓库合并到单个 Terraform 模块仓库功能引入于极狐GitLab 15.1…...

观测云:安全、可信赖的监控观测云服务

引言 近日&#xff0c;“TikTok 遭欧盟隐私监管机构调查并处以 5.3 亿欧元”一案&#xff0c;再次引发行业内对数据合规等话题的热议。据了解&#xff0c;仅 2023 年一年就产生了超过 20 亿美元的 GDPR 罚单。这凸显了在全球化背景下&#xff0c;企业在数据隐私保护方面所面临…...

【python】使用Python和BERT进行文本摘要:从数据预处理到模型训练与生成

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着信息爆炸时代的到来,海量文本数据的高效处理与理解成为亟待解决的问题。文本摘要作为自然语言处理(NLP)中的关键任务,旨在自动生成…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.3 相关性分析(PEARSON/SPEARMAN相关系数)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 5.3 相关性分析&#xff08;PEARSON/SPEARMAN相关系数&#xff09;5.3.1 相关性分析理论基础5.3.1.1 相关系数定义与分类5.3.1.2 Pearson相关系数&#xff08; Pearson Corr…...

Redis面试 实战贴 后面持续更新链接

redis是使用C语言写的。 面试问题列表&#xff1a; Redis支持哪些数据类型&#xff1f;各适用于什么场景&#xff1f; Redis为什么采用单线程模型&#xff1f;优势与瓶颈是什么&#xff1f; RDB和AOF持久化的区别&#xff1f;如何选择&#xff1f;混合持久化如何实现&#x…...

小程序滚动条隐藏(uniapp版本)

单独指定页面隐藏&#xff08;找到对应的scroll-view&#xff09; <style> /* 全局隐藏滚动条样式 */ ::-webkit-scrollbar { display: none; width: 0; height: 0; color: transparent; background: transparent; } /* 确保scroll-view组件也隐藏滚动条 */ …...

python基础:序列和索引-->Python的特殊属性

一.序列和索引 1.1 用索引检索字符串中的元素 # 正向递增 shelloworld for i in range (0,len(s)):# i是索引print(i,s[i],end\t\t) print(\n--------------------------) # 反向递减 for i in range (-10,0):print(i,s[i],end\t\t)print(\n--------------------------) print(…...

java反射(2)

package 反射;import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays;public class demo {public static void main(String[] args) throws Exception {// 通过类的全限定名获取对应的 Class 对象…...

C++核心概念全解析:从析构函数到运算符重载的深度指南

目录 前言一、构析函数1.1 概念1.2 语法格式 1.3 核心特性1.4 调用时机1.5 构造函数 vs 析构函数1.6 代码示例 二、this关键字2.1 基本概念2.2 核心特性2.3 使用场景2.3.1 区分成员与局部变量2.3.2 返回对象自身&#xff08;链式调用&#xff09;2.3.3 成员函数间传递当前对象2…...

如何巧妙解决 Too many connections 报错?

1. 背景 在日常的 MySQL 运维中&#xff0c;难免会出现参数设置不合理&#xff0c;导致 MySQL 在使用过程中出现各种各样的问题。 今天&#xff0c;我们就来讲解一下 MySQL 运维中一种常见的问题&#xff1a;最大连接数设置不合理&#xff0c;一旦到了业务高峰期就会出现连接…...

自由学习记录(58)

Why you were able to complete the SpringBoot MyBatisPlus task smoothly: Clear logic flow: Database → Entity → Service → Controller → API → JSON response. Errors are explicit, results are verifiable — you know what’s broken and what’s fixed. Sta…...

ES6 知识点整理

一、变量声明&#xff1a;var、let、const 的区别 作用域 var&#xff1a;函数作用域&#xff08;函数内有效&#xff09;。let/const&#xff1a;块级作用域&#xff08;{} 内有效&#xff0c;如 if、for&#xff09;。 变量提升 var 会提升变量到作用域顶部&#xff08;值为…...

《MATLAB实战训练营:从入门到工业级应用》高阶挑战篇-《5G通信速成:MATLAB毫米波信道建模仿真指南》

《MATLAB实战训练营&#xff1a;从入门到工业级应用》高阶挑战篇-5G通信速成&#xff1a;MATLAB毫米波信道建模仿真指南 &#x1f680;&#x1f4e1; 大家好&#xff01;今天我将带大家进入5G通信的奇妙世界&#xff0c;我们一起探索5G通信中最激动人心的部分之一——毫米波信…...

工程师 - 汽车分类

欧洲和中国按字母对汽车分类&#xff1a; **轴距**&#xff1a;简单来说&#xff0c;就是前轮中心点到后轮中心点之间的距离&#xff0c;也就是前轮轴和后轮轴之间的长度。根据轴距的大小&#xff0c;国际上通常把轿车分为以下几类&#xff08;德国大众汽车习惯用A\B\C\D分类&a…...

57.[前端开发-前端工程化]Day04-webpack插件模式-搭建本地服务器

Webpack常见的插件和模式 1 认识插件Plugin 认识Plugin 2 CleanWebpackPlugin CleanWebpackPlugin 3 HtmlWebpackPlugin HtmlWebpackPlugin 生成index.html分析 自定义HTML模板 自定义模板数据填充 4 DefinePlugin DefinePlugin的介绍 DefinePlugin的使用 5 mode模式配置…...

K8S - 金丝雀发布实战 - Argo Rollouts 流量控制解析

一、金丝雀发布概述 1.1 什么是金丝雀发布&#xff1f; 金丝雀发布&#xff08;Canary Release&#xff09;是一种渐进式部署策略&#xff0c;通过逐步将生产流量从旧版本迁移至新版本&#xff0c;结合实时指标验证&#xff0c;在最小化风险的前提下完成版本迭代。其核心逻辑…...

Qt中数据结构使用自定义类————附带详细示例

文章目录 C对数据结构使用自定义类1 QMap使用自定义类1.1 使用自定义类做key1.2 使用自定义类做value 2 QSet使用自定义类 参考 C对数据结构使用自定义类 1 QMap使用自定义类 1.1 使用自定义类做key QMap<key,value>中数据存入时会对存入key值的数据进行比较&#xff…...

数据可视化与分析

数据可视化的目的是为了数据分析&#xff0c;而非仅仅是数据的图形化展示。 项目介绍 项目案例为电商双11美妆数据分析&#xff0c;分析品牌销售量、性价比等。 数据集包括更新日期、ID、title、品牌名、克数容量、价格、销售数量、评论数量、店名等信息。 1、数据初步了解…...

基于大模型预测的产钳助产分娩全方位研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 二、产钳助产分娩概述 2.1 产钳助产定义与历史 2.2 适用情况与临床意义 三、大模型预测原理与数据基础 3.1 大模型技术原理 3.2 数据收集与处理 3.3 模型训练与验证 四、术前预测与准备 4.1 大模型术前风险预…...

通过混合机器学习和 TOPSIS 实现智能手机身份验证的稳健行为生物识别框架

1. 简介 随着日常工作、个人生活和金融操作对智能手机的依赖性不断增强,对弹性安全身份验证系统的需求也日益增长。尽管 PIN 码、密码和静态生物识别等传统身份验证方法仍可为系统提供一定的安全级别,但事实证明,它们容易受到多种威胁,包括敏感数据泄露、网络钓鱼、盗窃和…...

旅游设备生产企业的痛点 质检系统在旅游设备生产企业的应用

在旅游设备制造行业&#xff0c;产品质量直接关系到用户体验与企业口碑。从景区缆车、观光车到水上娱乐设施&#xff0c;每一件设备的安全性与可靠性都需经过严苛检测。然而&#xff0c;传统质检模式常面临数据分散、流程不透明、合规风险高等痛点&#xff0c;难以满足旅游设备…...

使用ESPHome烧录固件到ESP32-C3并接入HomeAssistant

文章目录 一、安装ESPHome二、配置ESP32-C3控制灯1.主配置文件esp32c3-luat.yaml2.基础通用配置base.yaml3.密码文件secret.yaml4.围栏灯four_light.yaml5.彩灯rgb_light.yaml6.左右柱灯left_right_light.yaml 三、安装固件四、HomeAssistant配置ESPHome1.直接访问2.配置ESPHom…...

【漫话机器学习系列】237. TSS总平方和

深度理解 TSS&#xff08;总平方和&#xff09;&#xff1a;公式、意义与应用 在机器学习与统计建模领域&#xff0c;评价模型好坏的重要指标之一就是方差与误差分析。其中&#xff0c;TSS&#xff08;Total Sum of Squares&#xff0c;总平方和&#xff09;扮演着非常关键的角…...

DeepSeek多尺度数据:无监督与原则性诊断方案全解析

DeepSeek 多尺度数据诊断方案的重要性 在当今的 IT 领域,数据如同石油,是驱动各类智能应用发展的核心资源。随着技术的飞速发展,数据的规模和复杂性呈爆炸式增长,多尺度数据处理成为了众多领域面临的关键挑战。以计算机视觉为例,在目标检测任务中,小目标可能只有几个像素…...

Spring Framework 6:虚拟线程支持与性能增强

文章目录 引言一、虚拟线程支持&#xff1a;并发模型的革命二、AOT编译与原生镜像优化三、响应式编程与可观测性增强四、HTTP接口客户端与声明式HTTP五、性能比较与实际应用总结 引言 Spring Framework 6作为Spring生态系统的基础框架&#xff0c;随着Java 21的正式发布&#…...