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

【Linux】进程的基本概念

目录

  • 概念
  • 描述进程-PCB
  • 如何查看进程
    • 通过系统目录进行查看
    • 通过ps指令进行查看
  • 通过系统调用获取进程的PID和PPID(进程标⽰符)
  • 通过系统调用创建子进程
    • 通过一段代码来介绍fork
      • 为什么要有子进程?
      • fork为什么给子进程返回0,给父进程返回子进程的PID
      • fork函数到底做了啥?
      • 一个函数是如何做到返回两次的?
      • 一个变量为什么会有不同的内容?
      • 通过fork来理解bash的命令行是如何来工作的?
  • end

概念

课本概念: 程序的一个执行实例,正在执行的程序等。(就是执行任务)
内核观点: 担当分配系统资源(CPU时间,内存)的实体。

  1. 我们写完代码后经过编译和链接后形成一个可执行文件,打开这个可执行文件就会加载到内存中交给CPU处理,CPU才能对其进行逐行的语句执行,而一旦将这个程序加载到内存后,我们就不应该将这个程序再叫做程序了,严格意义上将应该将其称之为进程。
    在这里插入图片描述

描述进程-PCB

  1. 系统当中可以同时存在大量进程,使用命令ps aux便可以显示系统当中存在的进程。
    在这里插入图片描述
  2. 而我们开机第一个运行的就是操作系统,运行操作系统就是一个进程。我们都知道操作系统是软件和硬件的管理者,那么进程也是操作系统来管理的。那么操作系统到底是如何来管理进程的呢?
  3. 这时我们就应该想到管理的六字真言:先描述,再组织t操作系统也是一样的,操作系统并不需要直接的和进程见面进行管理,而是对进程的属性进行描述,而操作系统只需要对这些描述的信息进行管理就行了。
  4. 那么描述进程属性是存放在哪里的呢。他是存放在一个叫做PCB的数据结构中,在Linux操作系统下,我们把他称为task_struct.
  5. 操作系统将每一个进程都进行描述,形成了一个个的进程控制块(PCB),并将这些PCB以双链表的形式组织起来。
    在这里插入图片描述
    把这些PCB用双链表组织起来,那么我们只需要遍历双链表就可以访问到所有的PCB,如果我们要删除某个进程的信息,就是删除双链表对应的节点,所以对进程的管理实际上就是数据结构的增删查改。

如何查看进程

通过系统目录进行查看

  • 在根目录下有一个叫做proc的文件,这里面就是我们Linux下的所有进程
    在这里插入图片描述
  • 这些进程的名字有的名字是一个数字,这些数字其实就是进程的PID(可以理解为身份证)
  • 如果我们想要查看进程的信息,就可以用ls指令来显示这些文件,这就是进程的信息
    在这里插入图片描述

通过ps指令进行查看

  • 单独使用ps命令,会显示所有进程信息。
    在这里插入图片描述
  • ps命令与grep命令搭配使用,即可只显示某一进程的信息。
ps aux | head -1 && ps aux | grep proc
  • 解释一下这个命令,ps aux拿到所有进程信息, |是管道,意思是把ps aux拿到的数据的输出作为 head -1 的输入,head -1 表示只取输入内容的第一行,也就是进程信息列表的表头 ,比如 F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 。交给下个指令
  • && :是逻辑与操作符,表示只有当左边的指令执行成功的时候才执行右边的指令
  • ps aux | grep proc, 当ps aux执行成功列出了所有的进程信息后把他的输出(所有的进程信息)作为给grep指令的输入,grep去查找这些进程信息中,proc名字的进程
    在这里插入图片描述

通过系统调用获取进程的PID和PPID(进程标⽰符)

  • 通过使用系统调用函数,getpid(自己的身份)和getppid(父进程的身份)即可分别获取进程的PID和PPID。
    我们可以通过一段代码来进行测试。
    在这里插入图片描述
  • 当运行该代码生成的可执行程序后,便可循环打印该进程的PID和PPID。
    在这里插入图片描述

通过系统调用创建子进程

通过一段代码来介绍fork

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

  • 这个时候你会发现,if和else if居然在同时运行

    这是为啥呢?在我们写过的程序中,怎么可能同时满足if又满足else if, 接下来我们就要对于这个现象进行剖析

为什么要有子进程?

之所有要有子进程,其实就是父进程想让子进程去绑他做一些事情,也就是说在父进程做事情的同时,子进程也可以同时做事情,父进程和子进程分别去做不同的事情。 那我们说完成一个任务总有知道是谁完成的吧,所以子进程和父进程都要有一个返回值。用来区分这个进程是子进程还是父进程。

  • 解决方法就是fork要有两个返回值!!——>所以返回不同的值的意义是为了区分不同的执行流,让父进程和子进程分别执行不同的代码块!!

fork为什么给子进程返回0,给父进程返回子进程的PID

因为在Linux系统中父进程和子进程的关系是1:n的,也就是说父进程可以有1个或多个子进程,但是子进程的父进程只能有1个。父进程如果有多个子进程,那么这个父进程就要通过这些子进程的pid来区分不同的子进程进行管理。而如果是子进程为啥返回0,因为子进程不需要父进程的pid,他可以通过getpid这个函数来获得。

fork函数到底做了啥?

  • 因为fork函数会创建一个进程,而进程=(内核数据结果)+代码和数据,所以首先:
    1. 创建一个task_struct结构体
    2. 吧进程的属性填写到task_struct里面
    3. 让子进程和父进程指向同样的代码,因为子进程继承了父进程的大多数属性。(跟子进程拷贝父进程的PCB有一定的关系,就是继承了pcb里面的属性,还有进程的地址空间,页表这些), 所以这里fork创建子进程后的代码是父进程和子进程共享的,那么return就会return两次,父进程return1次,子进程return1次。
    4. 这个时候补充一个知识:因为进程之间具有独立性,也就是说进程之间不能互相影响(比如说我关掉了洛谷这个进程并不影响我在爱奇艺上看电视),所以上面fork函数返回两次给id这个变量就会导致子进程修改一次,父进程修改一次。
    5. 这个时候就发生了写时拷贝

任何平台,进程都是具有独立性的,在子进程和进程共享代码的时候,因为代码是只读的,这是没有问题的。但是数据就不一样了,数据可以修改。那这个时候数据也是共享的,他们其中的一个改了数据就不行了。所以说,我们的子进程/父进程如果想要修改数据,就要想办法把修改的数据拷贝一份出来,让其指向新拷贝出来的那一块数据。这样才能做到进程之间互相不影响

一个函数是如何做到返回两次的?

  • 父子的代码是共享的,所以return ret也是属于代码,因此父子进程各返回了一次!
    在这里插入图片描述

一个变量为什么会有不同的内容?

  • 这就是因为子进程修改了数据导致触发了写时拷贝,导致一个变量会有两个值。但是有人说不对呀,变量地址不都是一样的吗?一个物理地址,怎么会有两个值?这就要等我后面说虚拟地址空间的时候来解释了
  • 但是要注意的是,子进程被创建好之后,究竟是先运行子进程还是先运行父进程,其实是由调度器(因为CPU只有一个,所以他的作用就是在当前进程中选一个合适的放到CPU中,进程之间会竞争CPU资源,所以调度器会遵循着自己的一套原则来保证进程之间的公平性)这个后面我会在进程优先级讲解

通过fork来理解bash的命令行是如何来工作的?

  • bash这个进程主要是用于做命令行解析的工作,bash创建一个子进程来替他执行指令操作,因为进程的独立性就是子进程失败了也不会影响bash这个进程。这样就达到了让bash这个进程专注于命令行解释的工作。
  • 什么事命令行解释?

在这里插入图片描述

end

感谢你的阅读,如果对你有帮助的话,给博主点一个赞吧。

http://www.xdnf.cn/news/7020.html

相关文章:

  • 虚幻引擎5-Unreal Engine笔记之Pawn与胶囊体的关系
  • 【android bluetooth 协议分析 01】【HCI 层介绍 5】【SetEventMask命令介绍】
  • Elasticsearch 初步认识
  • 用 UniApp 构建习惯打卡 App —— HabitLoop 开发记
  • 【cursor】有效解决
  • Denoising Score Matching with Langevin Dynamics
  • 【HarmonyOS 5开发入门】DevEco Studio安装配置完全指南
  • Flink 的窗口机制
  • 【ant design】ant-design-vue 4.0实现主题色切换
  • 【软考 McCabe度量法】
  • 深入理解指针(6)
  • 基因编辑根治胰腺癌-陈墨仙
  • Raft 协议:分布式一致性算法的核心思想
  • 欢乐熊大话蓝牙知识4:GATT 协议全解:蓝牙传数据到底怎么传?
  • 费马小定理
  • 数学复习笔记 16
  • 【Linux网络编程】Socket编程:协议理论入门
  • 数据库的规范化设计方法---3种范式
  • AIStarter Windows 版本迎来重磅更新!模型插件工作流上线,支持 Ollama / ComfyUI 等多平台本地部署模型统一管理
  • FPC连接器的未来趋势:柔性时代的核心桥梁
  • 【Redis】Hash 哈希
  • opencv4.11生成ArUco标记 ArUco Marker
  • IP68防水Type-C连接器实测:水下1米浸泡72小时的生存挑战
  • CodeBuddy 开发 JSON 可视化工具实录:JsonVision 的诞生之旅
  • 广东省省考备考(第十三天5.17)——言语:接语选择题(听课后强化练习)
  • 永磁同步电机公式总结——反电动势、磁链、转矩公式;三项、两项电压方程;坐标表换方程
  • 通过多线程获取VENC的H264码流数据
  • 11.1 LangGraph生产级AI Agent开发:状态管理与多智能体系统构建全解析
  • RAID学习笔记
  • USB和串口软件编程控制继电器通断