当前位置:网站首页>进程(下):进程控制、终止、等待、替换
进程(下):进程控制、终止、等待、替换
2022-08-02 03:32:00 【RNGWGzZs】
--------------“美好的事总会如约而至”
(1)进程控制:
① 如何理解fork有两个返回值?
父:子 ==1:N; 父进程不需要表示,子进程需要标识。
多个子进程执行不同任务,父进程需要通过id 区分子进程。
因此调用fork时候,内核会做:
1.分配新的内存块 和 内核数据 给子进程。
2.将父进程的代码 数据拷贝给子进程。
3.并把子进程添加到 系统进程调用列表当中。
4.fork返回,并执行调度。
②写时拷贝:
通常情况下,父子代码共享,数据也是(物理内存是一样的)。但是当一方试图写入时,为了保证各个进程的独立性,此时会发生写时拷贝。
为什么要写时拷贝?
①保证进程的独立性。
为什么不创建时就分开?
因为子进程不一定需要父进程的所有数据。
子进程不一定立马使用(按需分配);因此进行延时分配,本质是高效使用内存空间。
fork调用失败原因?
1.系统中太多程序
2.用户进程超过限制(OS进行的限制)。
(2)进程终止:
①进程退出码:
main函数返回值给了谁?操作系统
main函数也是函数,所以一定会被调用。返回值会返回给操作系统。
为什么要有返回值? ------------运行加载,完成工作,需要知道完成度。
途径:
echo $?
退出码0 、!0:
#include<string.h>
strerror(size_t i); //错误码
每种错误码,都有对应的错误含义。但这都是人为规定。
②进程退出:
1.exit:进程终止;并释放缓冲区的数据
_exit:进程终止,不做其余工作
2.异常退出:此时退出码已经没有任何意义了
3.进程终止,操作系统会做什么? 一定要去管理!
释放内存 数据结构 调度队列移除。
(3)进程等待:父进程等待
①等待必要性:回收子进程、获取其退出信息。
②进程等待方法:
1.wait:等待接收子进程返回的pid
#include<sys/wait.h>
pid_t wait(int* status)
小结:父进程通过wait 读取子进程的信息,僵尸状态也就自动改变。
在子进程运行期间(wait),父进程在做什么? 什么也没做------> 阻塞等待!!!
2.waitpid:指定等待进程
//记录子进程的状态
waitpid(pid_id pid,int* status,int options)
//有列表的监控脚本
while :; do ps ajx|head -1 && ps ajx | grep myproc |grep -v 'grep';echo "#########################" ; sleep 1 ;done;
等待成功!=子进程运行成功。
status:退出结果 ---------->查看子进程 运行状态
注:进程异常终止,本质上是因为收到信号。其退出码也没有任何价值。
此进程发生异常,收到信号,此时退出码也没有任何意义。
实际中一般用 宏检测:
WIFEXITED(status) //进程信号 0 与 !0
WEXITSTATUS(status) //进程退出码
多进程创建与等待:
补充:阻塞与非阻塞
//若pid没有返回 也就是子进程没有执行结束,不再等待子进程 返回0 不予等待
// 若正常退出 则返回子进程pid
pid_t ret=waitpid(id,&status,WNOHANG);
所以对父进程而言,需要不断去等子进程执行完。
(4)进程替换:
子进程执行新的进程。
进程替换函数:
函数 | .... |
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[]); | 数组+默认路径 |
int execve(const char *path, char *const argv[], char *const envp[]); | 数组+自定义路径 |
execl 其本质就是让程序加载到磁盘。
1.当前进程 再进行 程序替换,是否创建了新进程?
这里根本没有 创建新进程。只是把磁盘代码进行替换了而已。 进程!=可执行程序。
2.被替换后,后续的代码,是否能被读到?
答案是不能。
3. 函数调用失败,程序不会受到影响。但调用成功则不会返回!
4.运行具有独立性父子之间不会因为程序替换函数而受到影响。
函数接口的理解:
只需要理解 数组、列表 执行程序的参数的区别:
execv为例:
理解默认路径、自定义路径:
默认路径:
自定义路径(execle):
打印出null;
此时还不会打印出 这个未定义(MAVAL)的环境变量。
进程的相关内容也最后完结:希望对阅读的你有用。
祝你好运~
边栏推荐
- OneNET Studio与IoT Studio对比分析
- 分割回文串 DP+回溯 (LeetCode-131)
- 【Arduino connects SD card module to realize data reading and writing】
- 工业边缘网关究竟强大在哪里?
- Type c PD 电路设计
- Personal image bed construction based on Alibaba Cloud OSS+PicGo
- 【Arduino 连接DHT11 湿度和温度传感器】
- GM8775C规格书,MIPI转LVDS,MIPI转双路LVDS分享
- Typora use
- GM7150,振芯科技,视频解码器,CVBS转BT656/601,QFN32,替换TVP5150/CJC5150
猜你喜欢
【心率传感器与Arduino连接读取心率数据】
远程调试PLC,到底如何操作?
【MQ-3 酒精检测器与 Arduino检测酒精】
【Arduino connects DHT11 humidity and temperature sensor】
2019 - ICCV - 图像修复 Image Inpainting 论文导读《StructureFlow: Image Inpainting via Structure-aware ~~》
IDEA2021.2安装与配置(持续更新)
LT8918L LVDS转MIPI芯片技术支持资料
【plang 1.4.3】定时器的使用
【霍尔效应传感器模块与 Arduino】
Compatible with C51 and STM32 Keil5 installation method
随机推荐
【plang 1.4.5】编写坦克(双人)游戏脚本
向龙芯2K1000板子上烧写中标麒麟系统
MPU6050 加速度计和陀螺仪传感器与 Arduino 连接
MQ-5 可燃气体传感器与 Arduino 接口
引擎开发日志:场景编辑器开发难点
【MQ-3 酒精检测器与 Arduino检测酒精】
单火线开关设计详解
Type c PD 电路设计
【MQ-2 可燃气体和烟雾传感器与 Arduino 配合使用】
兼容C51与STM32的Keil5安装方法
【Arduino 连接DHT11 湿度和温度传感器】
野火ISO-V2学习
调试九法准则
联阳(ITE)IT66021FN:HDMI转RGB芯片 3D 资料
远程调试PLC,到底如何操作?
IDEA2021.2安装与配置(持续更新)
【水位传感器与 Arduino 连接测量水位】
出差电子流应用实战
如何用 Lightly 进行 Debug 断点调试?
移动云物联网预研及阿里云开发对比分析