【Linux】进程控制

目录

  • 一、进程创建
    • 1.fork创建子进程
    • 2.写时拷贝
  • 二、进程退出
    • 1.进程退出方式
    • 2.进程退出码
    • 3.exit 函数和 _exit 函数
  • 三、进程等待
    • 1.概念
    • 2.wait
    • 3.waitpid
    • 4.获取子进程status
  • 四、进程程序替换
    • 1.原理
    • 2.进程替换接口
      • ① execl
      • ② execv
      • ③ execlp
      • ④ execvp
      • ⑤ execle

一、进程创建

1.fork创建子进程

我们在前面学习进程的时候已经见过fork创建子进程
在这里插入图片描述
我们可以看到他的头文件是#include<unistd.h>
返回值是pid_t类型的,功能是创建一个进程
返回值,子进程中返回0,父进程中返回子进程的pid,创建出错则返回-1

以前我们只是知道fork具有创建进程的功能,现在我们学习一下fork后,操作系统还做了一些什么事情

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度

在这里插入图片描述

进程不仅仅是将代码和数据加载到内存上,还需要操作系统维护它的PCB、mm_struct、页表等等。子进程和父进程的所有代码都是共享的,只是fork之前的代码子进程不会执行

2.写时拷贝

子进程和父进程的数据采用写时拷贝,子进程不改变数据时,与父进程使用同一块空间,需要改变时操作系统会为子进程单独开辟一块空间。

在这里插入图片描述

二、进程退出

进程退出大致可以分为三种情况,①代码运行完毕,结果正确 ②代码运行完毕,结果错误 ③代码异常终止

1.进程退出方式

正常终止
从main返回
int main(){return 0;} 我们在写程序的时候在main函数最后都会加上一个return语句,这个语句实际上就是返回进程退出码的。
调用exit
调用_exit

异常退出
ctrl + c,信号终止

2.进程退出码

任何进程退出时,都会留下退出码,保存在PCB里面,操作系统根据退出码可以知道进程是否正常运行。

linux下有134个退出码,通常0表示正常退出,其他数字表示不同的错误。

所以这就是为什么main函数中的返回值是0的原因。

查看linux系统下的进程退出码:使用指令 echo $?
在这里插入图片描述

3.exit 函数和 _exit 函数

_exit函数
在这里插入图片描述
参数:status 定义了进程的终止状态,父进程通过wait来获取该值

exit函数
在这里插入图片描述
在这里插入图片描述

_exit: 强制终止进程,不要进行进程的后续收尾工作,比如刷新缓冲区。
exit:最后也会调用_exit, 但在调用_exit之前,还做了其他工作:

  1. 执行用户通过 atexit或on_exit定义的清理函数。
  2. 关闭所有打开的流,所有的缓存数据均被写入
  3. 调用_exit
    在这里插入图片描述
    在这里插入图片描述

三、进程等待

1.概念

概念:进程等待是进程的一种状态, 是父进程等待子进程退出时的一个过程。

为什么要有进程等待?

  • 子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。
  • 进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。
  • 父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出。
  • 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

2.wait

wait:
#include<sys/types.h> 头文件
#include<sys/wait.h> 头文件
pid_t wait(int*status); 函数
返回值: 成功返回被等待进程pid,失败返回-1。
参数: 输出型参数,获取子进程退出状态,不关心则可以设置成为NULL

在这里插入图片描述

3.waitpid

waitpid:
*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。
在这里插入图片描述

waitpid有三个参数,
pid_t pid :第一个参数可以指定等待进程的pid,意思就是waitpid可以等待一个指定的子进程退出,当pid>0,表示等待指定进程,pid<0,等待任意一个子进程。
WNOHANG: 第三个参数设置父进程等待方式为非阻塞等待。设置为0表示为阻塞等待。

4.获取子进程status

status:输出型参数,获取子进程退出信息。

wait和waitpid(第二个参数),都有一个status参数,该参数是一个输出型参数,由操作系统填充 。

status不能简单的当作整形来看待,可以当作位图来看待 ,只研究status低16比特位)

我们在观察进程是否正常退出的时候先去看他的退出信号,如果退出信号不为0,即使他的退出码为0,那也是异常终止,如果退出信息为0,去看他的退出码,退出码为0,说明程序正常运行完,正常退出,不为0,说明程序正常运行完,结果不对。

在这里插入图片描述
这里的退出信号表示的是,进程异常终止时的情况。

情况1:进程信号正常,进程退出码正常,进程正常运行完退出

在这里插入图片描述

情况2:程序正常运行完,结果不对
在这里插入图片描述

情况3:代码运行异常,信号不正常
在这里插入图片描述

四、进程程序替换

1.原理

进程不改变,仅替换当前进程的代码和数据。

程序本质就是一个文件,文件 = 程序的代码 + 程序数据。所以进程替换就是将指定 文件加载到进程的数据段和代码段,不会创建新的进程。

问题:既然父子进程代码是共享的,那么为什么子进程的代码改变不会影响父进程?
进程具有独立性,进程替换会更改代码区的代码,也要发生写时拷贝。

在这里插入图片描述

2.进程替换接口

在这里插入图片描述

命名理解

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

  • v(vector) : 参数用数组

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

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

① execl

在这里插入图片描述
执行一个程序需要两个步骤,①找到程序所在位置 ②加载执行程序
第一个参数顾名思义,就是找路径,后面的可变参数列表就是交代程序执行方式

在这里插入图片描述

execl系列的也会有返回值,当程序替换失败时会返回-1,此时我们并不需要接受返回值然后去判断,如果执行到execl后续代码时,我们知道该程序已经程序替换失败,此时我们可直接返回我们的退出码即可。
在这里插入图片描述

② execv

在这里插入图片描述
第一个参数还是路径,第二个参数是一个字符指针数组,数组中最后一个元素还是得NULL结尾
在这里插入图片描述

③ execlp

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

④ execvp

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

⑤ execle

在这里插入图片描述
第一个参数路径,第二个参数执行,第三个参数,传入环境变量,可以是自定义,也可以是传入全局的环境变量
我们在使用程序替换函数时,不仅可以替换系统指令,还可以替换为我们自己的程序。
在这里插入图片描述

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

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

相关文章

如何使用装rancher安装k8s集群(k8s集群图形化管理工具)

前言 kubernetes集群的图形化管理工具主要有以下几种&#xff1a; 1、 Kubernetes Dashborad: Kubernetes 官方提供的图形化工具 2、 Rancher: 目前比较主流的企业级kubernetes可视化管理工具 3、各个云厂商Kubernetes集成的管理器 4、 Kuboard: 国产开源Kubernetes可视化管理…

C++ 改善程序的具体做法 学习笔记

1、尽量用const enum inline替换#define 因为#define是做预处理操作&#xff0c;编译器从未看见该常量&#xff0c;编译器刚开始编译&#xff0c;它就被预处理器移走了&#xff0c;而#define的本质就是做替换&#xff0c;它可能从来未进入记号表 解决方法是用常量替换宏 语言…

提升代码可读性与可维护性:利用责任链模式优化你的Spring Boot代码

1. 基本介绍 责任链是一种非常常见的设计模式, 具体我就不介绍了, 本文是讲解如何在SpringBoot中优雅的使用责任链模式 1.1. 代码执行流程 基本步骤如下 : SpringBoot启动时, 需要获取 handler 对应Bean, 不同业务对应着不同的多个处理器, 比如 购票业务, 可能需要检查参数是…

运算符(个人学习笔记黑马学习)

算数运算符 加减乘除 #include <iostream> using namespace std;int main() {int a1 10;int a2 20;cout << a1 a2 << endl;cout << a1 - a2 << endl;cout << a1 * a2 << endl;cout << a1 / a2 << endl;/*double a3 …

GPU版本pytorch(Cuda12.1)安装教程

我们通过Pytorch官网安装torch的时候&#xff0c;会发现常常由于网速问题安装不成功&#xff0c;下面提供一种简单的方法可以成功安装Cuda12.1&#xff0c;亲测有效。 目录 一、常规方法 二、有效方法 2.1 创建并激活虚拟环境 2.2 添加清华源 2.3 安装torch 一、常规方法…

惠普NS1020激光打印机碳粉警告提示及添加碳粉方法

本文也适用于惠普NS1020、1020c 和 1020w 系列打印机。 通过碳粉量指示灯检查碳粉量。 如果碳粉量是满的或指示器显示 1&#xff0c;可选择添加一个碳粉或者忽略不添加。如果碳粉量指示灯显示 2或 2 和碳粉量警告感叹号图标 &#xff0c;则表示碳粉量不足或严重不足&#xff0…

Mysql--技术文档--MVCC(Multi-Version Concurrency Control | 多版本并发控制)

MVCC到底是什么 MVCC&#xff08;Multi-Version Concurrency Control&#xff09;是一种并发控制机制&#xff0c;用于解决并发访问数据库时的数据一致性和隔离性问题。MVCC允许多个事务同时读取数据库的同一数据&#xff0c;而不会相互干扰或导致冲突。 在传统的并发控制机制中…

远程教育:别催了,在线巡课真爽啊

随着远程教育和在线学习的兴起&#xff0c;教学活动的场景正逐渐从传统的实体教室转向虚拟的线上平台&#xff0c;这也催生了对教学质量监管的新需求。 在线巡课系统在这一背景下应运而生&#xff0c;它不仅能够实时观察教师的教学过程&#xff0c;还能够量化评估教学效果&…

Element——table排序,上移下移功能。及按钮上一条下一条功能

需求&#xff1a;table排序&#xff0c;可操作排序上移下移功能。判断第一行上移禁用和最后一行下移禁用&#xff0c;排序根据后端返回的字段 <el-table:data"tableData"style"width: 100%"><el-table-column type"index" label"序…

先进API生产力工具eqable HTTP,一站式开发调试工具推荐

简介 Reqable是什么? Regable Fiddler/Charles Postman Reqable是HTTP一站式开发调试国产化解决方案&#xff0c;拥有更便捷的体验&#xff0c;更先进的协议&#xff0c;更高效的性能和更精致的界面。 Reqable是一款跨平台的专业HTTP开发和调试工具&#xff0c;在全平台支持…

APSIM模型应用与参数优化、批量模拟

APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和Next Generation两个系列模型&#xff0c;能模拟几十种农作物、牧草和树木的土壤-植物-大气过程&#xff0c;被广泛应用于精细农业、水肥管理、气候变化、粮食安…

ElasticSearch总结

ES是什么 ES是一个天生支持分布式的搜索、聚合分析的存储引擎 基于Java开发 基于Lucene的开源分布式搜索引擎 ELK &#xff1a; elasticSearch Logstah Kibana 加入 Beats 后 ELK 改为 &#xff1a;Elastic stack ES解决了什么问题 ES解决的核心问题 &#xff1a; 1.海量数…

Vue2向Vue3过度核心技术工程化开发和脚手架

目录 1 工程化开发和脚手架1.1 开发Vue的两种方式1.2.脚手架Vue CLI 2 项目目录介绍和运行流程2.1 项目目录介绍2.2 运行流程 3 组件化开发4 根组件 App.vue4.1 根组件介绍4.2 组件是由三部分构成4.3 总结 5 普通组件的注册使用-局部注册5.1 特点&#xff1a;5.2 步骤&#xff…

爬虫异常处理之如何处理连接丢失和数据存储异常

在爬虫开发过程中&#xff0c;我们可能会遇到各种异常情况&#xff0c;如连接丢失、数据存储异常等。本文将介绍如何处理这些异常&#xff0c;并提供具体的解决代码。我们将以Python语言为例&#xff0c;使用requests库进行网络请求和sqlite3库进行数据存储。 1. 处理连接丢失 …

GD32-舵机的原理

GD32-舵机的原理 舵机的现一脉宽与舵机转动角度 旋转编码器的原理 顺时针&#xff1a;A的下降沿时&#xff0c;B处于高电平&#xff1b; 逆时针&#xff1a;A的下降沿时&#xff0c;B处于低电平&#xff1b; #ifndef _ENCODER_DRIVE_H #define _ENCODER_DRIVE_H#include &quo…

开源软件的崛起:历史与未来

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

5.Redis-string

string 字符串 字符串类型是 Redis 最基础的数据类型&#xff0c;关于字符串需要特别注意&#xff1a; 1.⾸先Redis中所有 key 的类型都是字符串类型&#xff0c;⽽且其他⼏种数据结构也都是在字符串类似基础上构建的&#xff0c;例如 list 和 set 的元素类型是字符串类型。 2…

每日一题 823. 带因子的二叉树

每日一题 823. 带因子的二叉树 难度&#xff1a;中等 思路&#xff1a; 取乘积&#xff0c;那么两个叶子节点相乘一定会得到一个更大的数&#xff0c;所以先排序以父节点为根节点的数的数量 以右节点为根节点的数的数量 * 以左节点为根节点的数的数量初始化列表&#xff0c;…

花5分钟判断,你的Jmeter技能是大佬还是小白!

jmeter 这个工具既可以做接口的功能测试&#xff0c;也可以做自动化测试&#xff0c;还可以做性能测试&#xff0c;其主要用途就是用于性能测试。但是&#xff0c;有些公司和个人&#xff0c;就想用 jmeter 来做接口自动化测试。 你有没有想过呢&#xff1f; 下面我就给大家讲…

多线程(二)

一.关于线程的常用操作 1.启动线程 run(): 对于run方法的覆写只是指定线程要做的任务清单&#xff0c;而不是真正的启动线程 start()&#xff1a; start()方法才是真正的在底层创建出一个线程&#xff0c;并且启动 2.中断线程 1.通过共享的标记来中断 package demo; impor…