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

进程控制(下)【Linux操作系统】

文章目录

  • 进程程序替换
    • 进程替换有关函数和指令
      • 函数:execl
      • 函数:execv
      • 函数:execlp
      • 函数:execvp
      • 函数:execvpe
    • 进程替换的原理
      • 为什么进程替换时,原进程的环境变量不会被覆盖?
    • 进程替换具体会造成什么影响
    • shell的本质

进程程序替换

进程替换有关函数和指令

函数:execl

头文件:unistd.h
返回值:int类型
①成功:就没有返回值,也用不了返回值
因为成功了execl之后的代码和数据就都被换上来的进程的代码和数据替换了,返回值根本用不出来

②失败:返回-1

参数:
①const char* path:要替换上来的可执行程序的绝对/相对路径

②const char* name:要替换上来的可执行程序的名字

③~n:要替换上来的可执行程序的选项
最后一个参数必须以nullptr结尾

参数3其实就是命令行参数中的数组argv中的元素
要替换上来的可执行程序在命令行如何执行[即:命令行参数argv数组的元素,最后必须以nullptr结尾]
在这里插入图片描述

作用:把执行这个函数的进程替换成指定路径的进程



函数:execv

头文件:unistd.h
返回值:int类型
①成功:就没有返回值,也用不了返回值
因为成功了execl之后的代码和数据就都被换上来的进程的代码和数据替换了,返回值根本用不出来

②失败:返回-1

参数:
①const char*path:要替换上来的可执行程序的绝对/相对路径

②char* const argv[]:就是把execl中的可变参数[第2个参数到第n个参数]先放进指针数组中,再传给函数
参数2其实就是命令行参数中的数组argv

作用:把执行这个函数的进程替换成指定路径的进程

execl和execv的区别
在这里插入图片描述
所以exec之后带v的就表示用数组把选项装起来再传给函数
带l的就表示直接把选项一个一个地传给函数



函数:execlp

头文件:unistd.h
返回值:int类型
①成功:就没有返回值,也用不了返回值
因为成功了execl之后的代码和数据就都被换上来的进程的代码和数据替换了,返回值根本用不出来

②失败:返回-1

参数:
①const char*file:要替换上来的可执行文件的文件名
为什么可以不用写绝对路径呢?
这是因为它会自动地拿着文件名,到环境变量PATH的路径集合里面去找

②~n:和execl一样的可变参数

所以带exec之后带p的,就表示不用传绝对路径,能自己去PATH里面找,直接传文件名字即可



函数:execvp

和execlp同理
就是第一个参数为可执行文件名的,第二个参数为选项表


函数:execvpe

头文件:unistd.h
返回值:int类型
①成功:就没有返回值,也用不了返回值
因为成功了execl之后的代码和数据就都被换上来的进程的代码和数据替换了,返回值根本用不出来
②失败:返回-1

参数:
①const char*file:要替换上来的可执行文件的文件名

②char* const argv[]:就是命令行参数中的数组argv

③char*const envp[] :环境变量表

有2种情况
1,直接用父进程的环境变量,那么就可以不使用这个接口(因为替换进程时不会覆盖环境变量)或者直接传environ

2,想给这个新替换上来的进程,一个新的环境变量表
就可以再自定义一个环境变量表,把这个新的环境变量表传进去
这样这个新替换上来的进程的环境变量就是新定义的环境变量表,而不是继承来的

在这里插入图片描述

把新的程序的代码和数据放入内存中,就是加载这个程序

所以:
execl等接口就相当于把一个程序加载到内存

execl等接口是系统调用的封装

execl等接口之间的关系:
在这里插入图片描述


除了execve是系统调用之外
其他的execl等接口都是封装了execve这个系统调用的函数



进程替换的原理

进程替换时,替换上来的进程会把原进程的代码和数据覆盖掉[默认不会覆盖环境变量,除非使用的替换函数是execvpe],顺便改页表的映射,栈区,堆区,全局区也会覆盖

但是原进程的PCB等内核数据结构不变
在这里插入图片描述

所以进程替换并非创建了一个新进程
因为
进程=内核数据结构+代码和数据进程替换只替换了代码和数据,以及修改了替换代码和数据带来的影响



为什么进程替换时,原进程的环境变量不会被覆盖?

shell的环境变量是从操作系统的配置文件里面读取出来的
shell再把读取出来的信息分析之后,再放入shell内部的全局的指针数组中

我们在命令行上执行的命令都是shell的子进程
绝大部分都是shell创建的子进程使用进程替换,搞出来的
而shell使用的进程替换函数是execvpe
shell就通过execvpe把自己全局的环境变量表传给所有子进程
execvpe会把环境变量和命令行参数存放在子进程的特定区域(用户环境区)在进程替换时这一部分区域的数据就不会被替换
就真正完成了环境变量的全局化

所以:
因为自从shell使用execvpe把自己的环境
变量给子进程后,execvpe会把这个环境
变量表放在进程的特定区域(用户环境区)

以后,shell的子进程再创建子进程时,就
知道哪些是环境变量了,就会把环境变量放进子进程的用户环境区
而程序再替换时,默认是不会覆盖用户环境区的



进程替换具体会造成什么影响

代码和数据被替换

进程地址空间大部分都会被覆盖(环境变量表默认保留,除非使用的是execvpe

③信号处理(Signal Handlers):
被忽略的信号(如 SIG_IGN):保持忽略状态。

自定义信号处理函数:会被重置为默认行为(如 SIG_DFL),因为原处理函数的代码已被替换,无法继续执行。

信号屏蔽字(Signal Mask):
子进程的信号屏蔽字(通过 sigprocmask 设置的阻塞信号集合)保持不变

替换之前设置的定时器也会清空



shell的本质

就是先让用户输入命令,然后shell把用户的命令分解
再使用fork创建子进程,再把分解后的命令传给execl等接口,把对应的程序加载到内存,进行执行

相关文章:

  • linux下C++性能调优常用的工具
  • AcWing 11:背包问题求方案数 ← 0-1背包
  • 科学研究:怎么做
  • [密码学基础]国密算法深度解析:中国密码标准的自主化之路
  • 计算机软考中级 知识点记忆——排序算法 冒泡排序-插入排序- 归并排序等 各种排序算法知识点整理
  • 腾讯云对象存储m3u8文件使用腾讯播放器播放
  • React 文章列表
  • 2024-04-19| Java: Documented注解学习 JavaDoc
  • 高可靠 ZIP 压缩方案兼容 Office、PDF、TXT 和图片的二阶段回退机制
  • 2025.04.19【Chord diagram】| 弦图绘制技巧大全
  • JavaScript 变量语法扩展
  • Ubuntu 25.04 “Plucky Puffin” 正式发布
  • tensor.repeat和tensor.repeat_interleave
  • Invicti-Professional-V25.4
  • 【Python标准库】数学相关的9个标准库
  • 八大排序之直接插入排序
  • ELK日志系统
  • Kubernetes控制平面组件:高可用 APIServer
  • 详解反射型 XSS 的后续利用方式:从基础窃取到高级组合拳攻击链
  • 定制一款国密浏览器(10):移植SM2算法前,解决错误码的定义问题
  • 大理杨徐邱再审后上诉案将于下周开庭:案发已逾32年,故意杀人罪去年被撤销
  • “走进电影”:虚拟现实电影产业有新进展
  • 用户称被冒用身份证异地办卡申请注销遭拒,澎湃介入后邯郸联通着手办理剥离
  • 【社论】家政服务提质扩容,为何被一提再提
  • 聚餐醉酒后骑车撞树身亡、家属起诉共饮者赔44万,法院已判
  • 陈吉宁龚正深入郊区镇村园区调研乡村振兴并召开现场会,明确这些重点工作