[Linux]进程创建➕进程终止

文章目录

  • 1.再谈fork()函数
    • 1.1fork()创建子进程 OS都做了哪些工作?
    • 1.2对上述问题的理解
    • 1.3写时拷贝进行父子进程分离的优势
    • 1.4了解eip寄存器和pc
    • 1.5了解进程的上下文数据
    • 1.6对计算机组成的理解
    • 1.7fork常规用法
    • 1.8fork调用失败的原因
  • 2.进程终止
    • 2.1进程终止时操作系统要做的工作
    • 2.2进程终止的常见方式
      • 1.main函数的返回值
      • 2.查看错误码对应的错误信息
    • 2.3如何用代码终止一个进程

1.再谈fork()函数

fork()函数
在这里插入图片描述

1.1fork()创建子进程 OS都做了哪些工作?

  1. 进程 = 内核数据结构 + 进程代码和数据 内核数据结构包括task_struct(进程控制块)和mm_struct(进程地址空间)和页表和映射关系 进程代码和数据是进程加载到内存时形成的
  2. 所以他做的工作有 以父进程task_struct为模板创建子进程的task_struct(对于PID进程状态优先级等自己重写)
  3. 创建进程地址空间 创建页表 创建映射关系 将代码和数据加载到内存
  4. 这里要注意 代码是共享父进程的 数据是写时拷贝

1.2对上述问题的理解

  1. fork()函数创建子进程 进程 = 内核数据结构 + 进程代码和数据 内核数据结构包括task_struct(进程控制块)和mm_struct(进程地址空间)和页表和映射关系 进程代码和数据是进程加载到内存时形成的
  2. 由于进程的独立性 子进程也要有自己的内核数据结构和进程代码和数据
    内核数据结构: 前面我们已经讲到子进程的task_struct是按照父进程的task_struct为模板创建的 大部分相同 少部分如PID自己创建
    代码: 实际上代码都是只读的 不可写/修改 所以代码是父子共享的
    数据: 像申请的堆空间 局部变量 等可能被修改 需要各自独有

现在来考虑数据的问题 创建子进程时并不是一开始就把父进程的数据拿来拷贝一份 原因:

  1. 子进程被创建不一定立即运行 立即运行也不一定立马访问数据空间 即便访问也不一定会修改/写入
  2. 所以不需要对不会被访问的/不会写入的数据进行拷贝 但是OS无法提前知道哪些空间不会被访问/或者被写 所以他不知道什么空间要拷贝 什么空间不要拷贝 对于要拷贝的空间(会写入/修改的空间) 即便你提前拷贝了 也不是立即写入/修改
  3. 综上 OS选择写时拷贝 即子进程要对某一空间修改/写入 才把父进程的对应空间拷贝(之前提到过)

1.3写时拷贝进行父子进程分离的优势

  1. 需要写入/修改 再分配空间拷贝内容 高效使用内存
  2. OS无法提前知道哪些空间不会写入/修改 哪些空间会提前写入/修改 即便知道了 对会写入/修改的空间提前拷贝了 子进程也不一定立即就写入/修改
  3. 抛开写时拷贝 对于C语言常量字符串 如const char* str0 = "hello";const char* str1 = "hello"; 这里str0和str1实际上执行同一块空间 因为那个字符串压根不会被修改只会读 也就完全没必要搞两份 话说到这了 编译器都知道在为代码分配虚拟地址时节省空间 对于直接在物理内存上的操作更要空间节省内存空间 在C++专栏string类模拟实现也讲到了写时拷贝
  4. 父子进程的数据需要分离以保证进程独立性 写时拷贝使得这个操作更为优雅的完成(延时申请空间 提高整机效率)

上述提到 fork()函数之后 父子进程代码共享 是fork()之后共享 还是所有共享 答案是所有共享 那么子进程为什么不从main()函数开头执行而是从fork()函数之后执行

  1. 代码汇编后 代码行数大大增多 每一行代码有自己编译器分配的内部虚拟地址(对于函数调用 A函数结束要调用B函数 那么A函数内部还要记录B函数的虚拟地址) 也有加载到内存时的外部物理地址
  2. 进程未结束前随时会被中断 如阻塞/挂起 当满足某种条件再次得到调度时 并不是再从第一行代码开始 而是从上一次结束开始 进程执行的位置是CPU负责记录的 CPU内有对应的寄存器 记录当前进程得到执行位置 寄存器在CPU内 只有一份 寄存器内的数据可以有多份
  3. 寄存器内的数据等 这些进程的上下文数据在子进程创建时 也要给子进程 子进程认为自己的eip初始值是fork()之后的代码
  4. 所以子进程可以看到所有的代码 但是它是从fork()之后执行的

1.4了解eip寄存器和pc

EIP和PC都是指令指针寄存器,用于存储下一条要执行的指令的地址。它们的区别在于它们所处的体系结构和操作系统环境不同。
PC指针是指程序计数器(Program Counter),也称为指令指针(Instruction Pointer),是一种寄存器,用于存储计算机正在执行的指令的地址。在CPU执行程序时,PC指针会不断地更新,以指向下一条要执行的指令的地址。在程序执行过程中,PC指针的值决定了程序的执行顺序。
EIP是指扩展指令指针(Extended Instruction Pointer),是x86架构中的一个寄存器,用于存储下一条要执行的指令的地址。与PC指针不同的是,EIP寄存器是在保护模式下使用的,而PC指针则是在实模式下使用的。此外,EIP寄存器还可以存储一些特殊的指令,如中断指令和异常指令的返回地址等。

在x86体系结构中,EIP是指扩展指令指针(Extended Instruction Pointer),而PC是指程序计数器(Program Counter)。在Linux 0.11的代码中,EIP和PC都被用来存储下一条要执行的指令的地址,但是它们的值是由不同的寄存器来维护的。在Linux 0.11中,EIP是由CPU自动维护的,而PC是由操作系统维护的。

1.5了解进程的上下文数据

进程上下文实际上是进程执行活动全过程的静态描述。具体的说,进程上下文包括计算机系统中与执行该进程有关的各种寄存器(例如通用寄存器,程序计数器PC,程序状态字寄存器PS等)的值,程序段在经过编译过后形成的机器指令代码集,数据集及各种堆栈值PCB结构。这里,有关寄存器和栈区的内容是重要的,例如没有程序计数器PC和程序状态寄存器PS,CPU将无法知道下一条待执行指令的地址和控制有关操作。

进程上下文是可以按照层次规则组合起来的。例如在UNIX System V中,进程上下文由用户级上下文,寄存器上下文以及系统级上下文组成。用户级上下文由进程的用户程序段部分编译而成的用户正文段,用户数据,用户栈组成。

1.6对计算机组成的理解

硬件只是一个机械设备 没有软件的交互 它就跟个铁疙瘩一样 但是并不是说他不重要 他是一系列指令的最终执行者 内存随时可以被读写 有页表的存在使得它不那么随意 硬件傻傻呼呼 有软件的配合使得它能做各种各样的工作 CPU傻傻呼呼(只会获取指令分析指令执行指令[CPU需要认识各种指令集]) 有寄存器的存在 使得CPU知道从哪获取怎么分析从哪执行

1.7fork常规用法

一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子
进程来处理请求。
一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。

1.8fork调用失败的原因

系统中有太多的进程
实际用户的进程数超过了限制

2.进程终止

2.1进程终止时操作系统要做的工作

  1. 释放进程申请的相关内核数据结构
  2. 释放进程对应的代码和数据
  3. 本质是释放系统资源

2.2进程终止的常见方式

a. 代码跑完,结果正确
b.代码跑完,结果不正确
c.代码没有跑完,程序崩溃时 退出码无意义 退出码对应的return语句没有被执行 比如对空指针赋值会直接崩溃而没有执行return语句 此时不再关注退出码 而是关注程序崩溃的原因

1.main函数的返回值

  1. 返回0: 运行结果正确
  2. 返回非0: 运行结果错误
  3. 返回给上一级进程 用来评判该进程执行结果是否正确 (返回给系统/父进程)
  4. echo $?: 获取最近一个进程执行完毕的退出码(main()函数的返回值–进程退出码)
  5. 非0值有无数个 不同的非零值标识不同的错误原因 当程序运行结束 结果不正确 根据退出码定位错误原因

有什么意义?

int main()
{int ret = 0;int sum = ADD(100);if(sum != expected){ret = 1;}return ret;
}

通过main()函数的返回值和查看进程的退出码 可以判断代码运行结果是否正确

2.查看错误码对应的错误信息

在这里插入图片描述

在这里插入图片描述

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

ls进程的退出码和main的一样

在这里插入图片描述

kill进程的退出码和main的不一样

在这里插入图片描述
即可以使用这些退出码和含义 也可以自己设计一套退出方案

2.3如何用代码终止一个进程

  1. main()函数 return语句 return 退出码 其他函数内部的return是结束了这个函数
  2. exit()/_exit() 在代码任何地方调用都直接终止进程
  • exit()是个C语言库函数 _exit()是个系统调用接口
  • exit()使得程序结束时进程终止前会执行用户定义的清理函数 会冲刷缓冲区/关闭流 但是 _exit()直接终止进程
  • OS为了让外来者易于操作/访问 设计了一系列调用接口 由于这些接口含不够简便 大佬有对这些接口进行封装形成库函数 实际上exit()底层调用的就是_exit()
  • printf("hello"\n)数据保存在缓冲区 这个缓冲区一定不在OS内部 如果是OS维护的 那么_exit()终止进程时也可以刷新缓冲区 这个缓冲区是C标准库维护的
    在这里插入图片描述 在这里插入图片描述

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

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

相关文章

输入一个数n,输出大写字母X c++ 描述 用例输入 1 4 用例输出 1 d d c c b b a b b c c d d

输入一个数n&#xff0c;输出大写字母X c 描述 用例输入 1 4 用例输出 1 d d c c b b a b b c c d d 以下是使用C编写的输出大写字母X的程序&#xff1a; #include <iostream> #include <cmath> int main() {int n;std::cout << "请输入一个数n&…

人工智能-注意力机制之Transformer

Transformer 比较了卷积神经网络&#xff08;CNN&#xff09;、循环神经网络&#xff08;RNN&#xff09;和自注意力&#xff08;self-attention&#xff09;。值得注意的是&#xff0c;自注意力同时具有并行计算和最短的最大路径长度这两个优势。因此&#xff0c;使用自注意力…

13年老鸟总结,性能测试方法汇总+性能响应很慢排查方法(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试包含哪…

windows的bat文件(学习笔记)

简介 通过windows的cmd执行的批处理&#xff0c;扩展名可以是.bat或.cmd&#xff08;类似linux的shell脚本&#xff09; 所有语句符号不区分大小写 帮助提示信息&#xff1a;命令 /? 1 基本语法 (1) 注释&#xff1a;rem 注释文本不执行 (2) 关闭盘符输出&#xff1a;e…

Java实现-数据结构 2.时间和空间复杂度

.如何衡量一个算法的好坏&#xff1a;时间复杂度和空间复杂度 算法效率分为时间效率和空间效率&#xff0c;时间效率称为时间复杂度&#xff0c;空间效率称为空间复杂度 时间复杂度 算法的时间复杂度是一个数学函数&#xff0c;它描述了算法的运行时间&#xff0c;一个算法执…

读书笔记:《宽客人生:依曼纽尔·德曼》

金融工程&#xff0c;也叫数量金融&#xff0c;洞察了证券价值与不确定性之间的关系。 布莱克-斯科尔斯模型可以告诉我们如何利用标的股票来复制期权&#xff0c;以及复制期权的成本&#xff0c;做市商利用此来复制期权&#xff0c;以规避无法从其他人那里购买合适价格的期权的…

vim+xxd编辑十六进制的一个大坑:自动添加0x0a

问题描述 今天在做一个ctf题&#xff0c;它给了一个elf文件&#xff0c;我要做的事情是修复这个elf文件&#xff0c;最后执行它&#xff0c;这个可执行文件会计算它自身的md5作为这道题的flag。我把所有需要修复的地方都修复了&#xff0c;程序也能成功运行&#xff0c;但是fl…

奇怪的问题 a==1 a==2 a==3

a 1 && a 2 && a 3 题目很简单&#xff0c;只要让if语句中的判断条件成立即可。 if (a 1 && a 2 && a 3) {console.log(win!!!); }首先分析题目&#xff0c;题目的意思只要我们能够让a同时与1,2,3相等的话&#xff0c;那么此时就成功了…

【电路笔记】-快速了电阻

电阻类型 文章目录 电阻类型1、概述2、电阻器的组成类型2.1 碳电阻器2.2 薄膜电阻器2.3 绕线电阻器 3、总结 电阻器是所有电子元件中最基本、最常用的元件&#xff0c;人们几乎认为电阻器是理所当然的&#xff0c;但它们在电路中起着至关重要的作用。 1、概述 有许多不同类型的…

SpringCloud之Gateway(统一网关)

文章目录 前言一、搭建网关服务1、导入依赖2、在application.yml中写配置 二、路由断言工厂Route Predicate Factory三、路由过滤器 GatewayFilter案例1给所有进入userservice的请求添加一个请求头总结 四、全局过滤器 GlobalFilter定义全局过滤器&#xff0c;拦截并判断用户身…

深入解析:如何开发抖音票务小程序

当下&#xff0c;开发抖音票务小程序成为了吸引年轻用户群体的一种创新方式。本文将深入解析如何开发抖音票务小程序&#xff0c;探讨关键步骤和技术要点。 1.确定需求和功能 考虑到抖音的用户特点&#xff0c;可以加入与短视频相关的票务功能&#xff0c;如在线购票、观影记录…

[网络] 3. HTTP 3 与 HTTP 2 有什么区别

协议不同 HTTP2 是基于 TCP 协议实现的 HTTP3 是基于 UDP 协议实现的QUIC HTTP3 新增了 QUIC 协议来实现可靠性的传输握手次数 HTTP2 是基于 HTTPS 实现的&#xff0c;建立连接需要先进行 TCP 3次握手&#xff0c;然后再进行 TLS 3次握手&#xff0c;总共6次握手。 HTTP3 只需要…

IDEA中的Postman?完全免费!

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

Jenkins用126邮箱发邮件为什么发不出去

1、检查 Jenkins Location中的邮件地址配置与发邮件的地址配置是否一致 Manage Jenkins -》 system 2、检查地址和端口号 3、检查邮箱的登录配置是否正确&#xff08;这个地方的配置方式网上一抓一大把&#xff0c;自己搜一下就好&#xff09; 4、126邮箱发邮件不需要勾选ssl协…

在浏览器中直接打开PDF

1 使用iframe标签 <iframe src"./test.pdf" height"900px;" width"800px"></iframe> 如果PDF是base64参考如下 <iframe id"pdfView" width"100%" height"100%" allow"fullscreen" typ…

Blender学习--模型贴图傻瓜级教程

Blender 官方文档 1. Blender快捷键&#xff1a; 快捷键说明 按住鼠标滚轮&#xff1a;移动视角Tab&#xff1a;切换编辑模式和物体模式鼠标右键&#xff1a; 编辑模式&#xff1a; 物体模式&#xff1a; 其他&#xff1a; 2. 下面做一个球体贴一张纹理的操作 2.1 效果如下…

A-莲子的软件工程学【算法必会题目】(JavaPythonC++实现)

文章目录 A-莲子的软件工程学题目背景解题思路Python题解代码Java题解代码C++题解代码代码OJ评判结果代码讲解Python 代码解释:Java 代码解释:C++ 代码解释:寄语A-莲子的软件工程学 题目背景 在宇宙射线的轰击下,莲子电脑里的一些她自己预定义的函数被损坏了。 对于一名…

VM虚拟机中Ubuntu14.04安装VM tools后仍不能全屏显示

1、查看Ubuntu所支持的分辨率大小。 在终端处输入&#xff1a; xrandr&#xff0c;回车 2、输入你想设置的分辨率参数。 我设置的为1360x768&#xff0c;大家可以根据自己的具体设备设置。 在终端输入&#xff1a;xrandr -s 1360x768 注意&#xff1a;这里1360后边是字母 x 且…

Selenium-介绍下其他骚操作

Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器&#xff08;如 Chrome、Opera 和 Microsoft Edge&#xff09;中的工具&#xff0c;用于帮助开发人员调试和研究网站。 借助 Chrome DevTools&#xff0c;开发人员可以更深入地访问网站&#xf…

交叉编译 和 软硬链接 的初识(面试重点)

目录 交叉编译的初认识Q&A Q1: 编译是什么&#xff1f; Q2: 交叉编译是什么&#xff1f; Q3: 为什么要交叉编译 Q3.1&#xff1a;树莓派相对于C51大得多&#xff0c;可以集成编译器比如gcc&#xff0c;那么树莓派就不需要交叉编译了吗&#xff1f; Q4: 什么是宿主机和…