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。
放在后面单独写一篇文章。

在这里插入图片描述

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

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

相关文章

基于mediapipe深度学习的眨眼检测和计数系统python源码

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 人工智能算法python程序运行环境安装步骤整理_本地ai 运行 python-CSDN博客 3.部分核心程序 &…

(二)毛子整洁架构(CQRS/Dapper/DomianEvent Handler)

文章目录 项目地址一、Application 层1.1 定义CQRS的接口以及其他服务1. Command2. IQuery查询3. 当前时间服务接口4. 邮件发送服务接口 1.2 ReserveBooking Command1. 处理传入的参数2. ReserveBookingCommandHandler3. BookingReservedDomainEvent 1.3 GetBooking Query1. 创…

数据结构与算法:图论——最短路径

最短路径 先给出一些leetcode算法题&#xff0c;以后遇见了相关题目再往上增加 最短路径的4个常用算法是Floyd、Bellman-Ford、SPFA、Dijkstra。不同应用场景下&#xff0c;应有选择地使用它们&#xff1a; 图的规模小&#xff0c;用Floyd。若边的权值有负数&#xff0c;需要…

uniapp-商城-43-shop 后台管理 页面

后台管理较为简单&#xff0c;主要用于后台数据的管理&#xff0c;包含商品类别和商品信息&#xff0c;其实还可以扩展到管理用户等等 1、后台首页 包含 分类管理 商品管理 关于商家等几个栏目 主要代码&#xff1a; <template><view class"manage">…

LeetCode 1. 两数之和(Java)

LeetCode 1. 两数之和&#xff08;暴力 vs 哈希表&#xff09; 题目描述 给定一个整数数组 nums 和一个整数 target&#xff0c;要求找出数组中和为目标值的两个数&#xff0c;并返回它们的下标。假设每个输入只有一种答案&#xff0c;且同一元素不能重复使用。 示例&#xf…

《软件项目管理》笔记一

软件项目管理概述 项目管理属于软件工程的组成之一&#xff0c;另外两部分为&#xff1a;软件开发&#xff0c;过程改进。 参考书如下&#xff1a; 1.1 项目与软件项目 1、项目&#xff1a; 为了创造一个唯一的产品或提供一个唯一的服务而进行 的临时性的努力。 2、项目的…

深度学习:智能车牌识别系统(python)

这是一个基于opencv的智能车牌识别系统,有GUI界面。程序能自动识别图片中的车牌号码,并支持中文和英文字符识别,支持选择本地图片文件,支持多种图片格式(jpg、jpeg、png、bmp、gif)。 下面,我将按模块功能对代码进行分段说明: 1. 导入模块部分 import tkinter as tk…

Redis 持久化机制全面解析:RDB 与 AOF 的原理与实践

目录 前言1. Redis 持久化的总体思路2. RDB&#xff1a;快照机制详解2.1 RDB 的工作原理2.2 RDB 的优势2.3 RDB 的局限性 3. AOF&#xff1a;追加日志机制详解3.1 AOF 的工作原理3.2 AOF 的优势3.3 AOF 的缺陷 4. RDB 与 AOF 的对比分析4.1 数据丢失风险4.2 文件大小与恢复速度…

混淆矩阵(Confusion Matrix)

混淆矩阵&#xff08;Confusion Matrix&#xff09;是一个用于评估分类模型性能的工具&#xff0c;特别是在机器学习和统计学领域。它展示了模型预测结果与实际结果之间的关系。混淆矩阵通常用于二分类或多分类问题中&#xff0c;但也可以扩展到更多类别的情况。 一、混淆矩阵…

TB6600HG是一款PWM(脉宽调制)斩波型单芯片双极性正弦波微步进电机驱动集成电路。

该驱动器支持电机的正向和反向旋转控制&#xff0c;并具有多种激励模式&#xff0c;包括2相、1-2相、W1-2相、2W1-2相和4W1-2相。 使用这款驱动器&#xff0c;只需时钟信号即可驱动2相双极性步进电机&#xff0c;且振动小、效率高。 主要特点&#xff1a; 单芯片双极性正弦波…

【论文阅读】Towards Stable Backdoor Purification through Feature Shift Tuning

NeurIPS 2023 & 2024 Spotlight https://github.com/AISafety-HKUST/Backdoor_Safety_Tuning 我们的贡献包括&#xff1a; 我们对各种调整策略进行了广泛的评估&#xff0c;发现普通的微调&#xff08;FT&#xff09;和简单的线性探测&#xff08;LP&#xff09;在高投毒率…

创龙全志T536全国产(4核A55 ARM+RISC-V+NPU 17路UART)工业开发板硬件说明书

前 言 本文档主要介绍TLT536-EVM评估板硬件接口资源以及设计注意事项等内容。 T536MX-CXX/T536MX-CEN2处理器的IO电平标准一般为1.8V、3.3V,上拉电源一般不超过3.3V或1.8V,当外接信号电平与IO电平不匹配时,中间需增加电平转换芯片或信号隔离芯片。按键或接口需考虑ESD设计…

Jenkins忘记admin密码后的恢复步骤

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 时间较长没有使用…

React 组件prop添加类型

给函数的props做注解 import { useState } from reacttype Props { className:string,title?:string } // 自定义一个Button组件 function Button(props:Props){// 解构出classname\const {className} propsreturn <button className{className}>点击我</button&g…

如何使用docker配置ros-noetic环境并使用rviz,gazebo

参考链接&#xff1a;【Ubuntu】Docker中配置ROS并可视化Rviz及Gazebo_docker ros-CSDN博客 前言&#xff1a; 其实这个东西是相当必要的&#xff0c;因为我们有时候需要在一台电脑上跑好几个项目&#xff0c;每个项目都有不同的依赖&#xff0c;这些依赖冲突搞得人头皮发麻&…

(已完结)完美解决C盘拓展卷是灰色的无法扩容的问题以及如何正确地在WINDOS上从一个盘扩容到C盘

众所周知&#xff0c;window系统在“计算机”管理中自带了一个磁盘管理系统 但是在使用过程中会出现各种各样无法扩容的毛病。 第一&#xff1a;首先排查&#xff0c;大多数人在扩容之前忽视了一点就是&#xff0c;我们现代的很多新机器都是默认开启BitLocker加密的&#xff…

阿里云服务器-centos部署定时同步数据库数据-dbswitch

前言&#xff1a; 本文章介绍通过dbswitch工具实现2个mysql数据库之间实现自动同步数据。 应用场景&#xff1a;公司要求实现正式环境数据库数据自动冷备 dbswitch依赖环境&#xff1a;git ,maven,jdk 方式一&#xff1a; 不需要在服务器中安装git和maven&#xff0c;直接用…

leetcode 141. Linked List Cycle

题目描述&#xff1a; 代码&#xff1a; 用哈希表也可以解决&#xff0c;但真正考察的是用快慢指针法。 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Soluti…

微软输入法常用快捷键介绍以及调教技巧

微软输入法&#xff08;Microsoft Pinyin Input Method&#xff09;是 Windows 系统内置的中文输入工具&#xff0c;以其高效、智能化的特点广受用户喜爱。掌握其常用快捷键和特殊模式可以显著提升输入效率。本文将介绍微软输入法在 Windows 10/11 环境下的常用快捷键及 U 模式…

Paddle Serving|部署一个自己的OCR识别服务器

前言 之前使用C部署了自己的OCR识别服务器&#xff0c;Socket网络传输部分是自己写的&#xff0c;回过头来一看&#xff0c;自己犯傻了&#xff0c;PaddleOCR本来就有自己的OCR服务器项目&#xff0c;叫PaddleServing&#xff0c;这里记录一下部署过程。 1 下载依赖环境 1.1 …