Liunx:理解进程概念

news2024/9/20 22:12:15

一、进程概念

进程有两种可以理解的方式:

1、已经加载到内存中的程序,叫做进程。

2、正在运行的程序,叫做进程

从概念上挺好理解的,我们运行一个程序必然要通过CPU,所以自然需要加载到内存中……

          但我们应该关注的是,OS中不仅仅只有一个进程,可能运行着多个进程(比如我们可能同时运行着qq和qq音乐),所以OS必须要将进程管理起来!!根据我们以往的管理经验,我们需要先描述再组织!!

二、描述进程-PCB

           如何描述进程呢??

先思考:人是如何辨别事物或者对象的??

——>比如你在放学路上见到一个女生一见钟情,于是你记住了他的样貌,开始像别人打听这个女生,因为你不认识这个女生,所以你会对他进行描述,比如说长得很漂亮、水灵的眼睛、瓜子脸……当你提供的特征越来越多的时候,认识他的人或许就能通过你的描述找到这个女生。而这个过程中,这个女生的各种特征其实就是他的属性,所以我们可以得出一个结论:人是通过属性去辨别事物和对象的,当属性足够多的时候,这一堆属性的集合,就是目标对象!

         所以我们推断出,任何一个进程加载到内存时,OS需要创建一个描述进程的结构体对象——PCB(process ctrl block进程控制块) ,而他的本质就是对进程属性集合的描述!

        Linux操作系统下的PCB是task_struct,他是是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息

task_struct的内容:

1、标示符: 描述本进程的唯一标示符,用来区别其他进程。

有点类似学校里每个学生的学号,是一个唯一标识,方便我们通过标示符来管理进程

2、状态: 任务状态,退出代码,退出信号等。

OS中同时存在多个进程,所以可能有的进程正在运行、有的正在休眠、有的在正在待定、有的即将销毁……也就是说每个进程当前可能都处于某一种状态

3、优先级: 相对于其他进程的优先级。

OS中有多个进程,所以先执行谁肯定是要有一个标准的,所以进程之间可能存在对应的优先级关系

4、程序计数器: 程序中即将被执行的下一条指令的地址。

以前我们在学习函数栈帧的时候,我们知道代码是从上往下运行的,但是这个过程中可能会遇到出现某个函数需要我们进行跳转,这个时候当前的栈帧会暂时保存着,然后当跳转过去的相关代码执行结束后再返回之前栈帧的位置继续运行。但是由于OS中不仅仅只有一个进程,所有有可能这个进程在执行的时候可能会被一些切换给中断,转而去执行别的进程,然后该进程可能会进入休眠模式,而后期我们可能还会去唤醒这个进程,这个时候由于之间的栈帧被销毁了,所以已经不记得执行到哪句代码了,因此程序计数器存在的意义就是帮助没我们记住即将被执行的下一条指令的地址!举个更好理解的例子就是,比方说你正在数一堆书,当你数到50的时候,这个时候突然一个电话告诉你外卖到了,为了不让外卖员等太久,你需要暂停当前的工作马上下去,但是你又怕你数过的数字忘记了,所以你就把他记在本子上,当你取完外卖后,你就可以通过从本子上的数字继续往下数!

5、内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针(我们一个可执行程序要运行还需要有对应的数据和代码,所以PCB对象必然需要有一个指针指向这块空间,当进程响应的时候能够及时找到,另一方面可能会存在多种数据类型的指针,为了满足不同场景下的需求——通过数据结构和算法

6、上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。

7、I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。

8、记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

可能会包含进程的一些运行时间,其实对进程的调度来说是有作用的,因为在多个进程的情况下,只有一个CPU,所以先将哪个进程放到CPU里其实是由调度器决定的,而调度器除了考虑进程状态和一些优先级之外,他会尽可能秉持着公平的原则,比如说有尽可能地优先让执行时间短的进程优先去调度。

9、其他信息

Linux(内核剖析):04---进程之struct task_struct进程描述符、任务结构介绍_struct task linux .h文件-CSDN博客

       而一个可执行程序要运行,就需要由OS创建一个PCB,但具体应该按照什么逻辑去运行是取决于你的数据和代码的,所以我们可以得出  进程=内核PCB数据结构对象+你自己的代码和数据

三、组织进程

        我们知道进程=内核PCB数据结构对象+你自己的代码和数据,但是OS本质上是对PCB做管理,他并不关心你的代码和数据,因为他只要能找到PCB,就可以通过他里面的一个相关的指针去找到对应的代码和数据,然后再交给CPU去运行!!举个例子就好比如HR对人才的管理本质上就是对简历进行管理,然后安排面试的时候再通过简历来找到你的相关信息。

       但是PCB特别多,所以我们需要想办法管理起来,其实在我们的Linux中task_struct主要是以双链表的形式组织起来,你可能会疑惑,使用一个顺序表来存储不是更好吗??其实在OS内部对于进程的管理方式并没有像我们以前学的数据结构那么纯粹,他的场景会更加复杂,也就是说该进程可能会需要根据不同的需求被存储在队列中、双链表中、二叉树中、栈中……所以将进程按照节点的方式链接起来其实会更方便我们将这个进程放在不同的数据结构中,然后我们可以通过对应的指针信息来讲他们更好地管理起来

      举个例子,比如说我在当前进程中有一个队列指针,因为在OS中可能会有一些存储进程指针的运行队列和等待队列,如果你想让这个进程去哪个队列,你就可以通过修改队列指针的链接队形做到,从而实现更加灵活的管理。

      所以对进程管理工作取决于你把他放入哪个正在被组织的数据结构中,因为不同的数据结构有不同的特点,所以背后对应的就是不同的算法,而不同的算法对应的就是不同的应用场景。 

四、查看进程

我们电脑开机的时候,其实就是将OS从外设搬到内存中,因为只有在内存中才能对进程进行管理

4.1 ps ajx指令查看所有进程

为了方便观察我们可以写一个死循环的代码,然后去观察该进程 

 命令:ps axj | head -1 && ps axj | grep mycode

思考:为什么会出现第二行这样的进程??

——>因为所有的指令也是要变成进程才能运行,而这个是grep指令的进程,因为这个进程里面也有对应的关键字所以也会显示出来!

      我们给这个可执行程序写的是死循环的,所以会一直运行下去,但是我们可以用kill指令利用标示符强制杀死这个进程!

命令:kill -9 进程标示符

 4.2 /proc

       /proc目录里面存储都是内存级的文件!!在关机时会消失,开机时又会出现,他是对动态运行的所有进程的一个可视化信息!!

      蓝色表示的是目录文件,因为一个进程里面可能会存在很多信息!!我们可以试着进去看看

1、其中exe说明当前的进程是可以找到自己要执行的代码的!!(可视化出来了)

2、cwd表示的是当前进程的工作目录(current work dir),所以为什么你fopen出来的新文件会被默认放在当前目录,这其实是由该进程的cwd决定的!!

五、通过系统调用获取进程标识符

5.1 理解PPID

进程id(PID)

父进程id(PPID)

思考:什么是PPID呢??我们来看看刚刚执行程序的PPID是什么进程

我们会发现我们可执行程序的父进程是 -bash命令行。

       为什么会这样去设计呢??我们都知道其实bash命令行的作用一方面是解释命令,另一方面是为了阻止用户的非法操作,而我们每一条指令或者是可执行程序其实都是一个进程,因此我们的bash命令行其实是先创建了一个子进程去执行对应的指令,然后自己就可以继续去帮助别的指令创建进程,这样的好处就是一旦子进程崩了,并不会影响bash命令行进程处理其他的指令!!

 5.2 系统调用接口getpid

命令:man 3 getpid

 

重启机器后 

       我们会发现就是当我们重新运行程序的时候,只会改变子进程的id,父进程id并不会改变,而当我们把机器关了重新开了的似乎,父进程id却改变了,这说明父进程(bash命令行)是在打开机器的时候就创建好的一个进程!

介绍一条可以时刻监控进程的命令: while :; do ps ajx | head -1 ;ps ajx | grep mycode | grep -v grep;echo "----------------------------";sleep 1;done

六、通过系统调用创建进程-fork(重要) ​​​​​

命令:man 3 fork

 以下这句话的意思是:如果成功了,会返回一个子进程的pid给父进程,然后还会返回一个0给子进程,如果失败,返回-1给父进程,没有子进程被创建!!  ——>这说明fork有两个返回值!!

为了方便观察后面的结果,我们先写一段代码

 运行之后我们会发现一个非常惊奇的现象:竟然if和else if同时在进行!!!

       而后我们就要根据以上两个现象,我们大概可以知道fork其实创建了一个子进程,而后我们要针对这个现象进行系统地分析!!

6.1 为什么会需要子进程??

       之所以会多此一举搞一个子进程,其实是为了让父和子同时执行不同的事情——>因此我们就要想办法让父和子执行不同的代码块——>解决方法就是fork要有两个返回值!!——>所以返回不同的值的意义是为了区分不同的执行流,让父进程和子进程分别执行不同的代码块!!

6.2 fork为什么要给子进程返回0,给父进程返回子进程pid?

       因为一个父亲可以有多个子女,但是一个子女只能有一个父亲。所以对于父进程来说他未来可能需要去控制子进程,所以就需要子进程的PID用来标定子进程的唯一性)。而子进程只需要用getppid就知道其父进程了!所以我们返回个0就可以了(找到父进程基本不耗费什么成本)。

6.3 fork函数究竟都干了什么?

因为fork函数会创建一个子进程,而进程=内核数据结构(task_struct)+代码+数据,所以首先

1、要先创建一个task_struct的结构体

2、填充该结构体的内容

3、让子进程和父进程指向同样的代码 ——>父子进程的代码是共享的(因为代码是不可修改的)

4、根据需求发生写时拷贝 (重点!!)

      任何平台,进程都是具有独立性的,就是我结束了一个进程并不会影响其他的进程,所以父进程和子进程在共享代码的时候,由于代码不能修改,所以是没有问题的,你读你的我读我的,相互之间并不影响,但是如果是数据就不一样了,数据是可以修改的所以我改了可能你也会改,因此从理论上来说,我们的子进程必须想办法拷贝一份相同的数据且独立的数据出来!!

     但是其实这样也不太可取,因为父进程的数据可能有非常多,但是我们的子进程可能只是共享了其中一部分的代码,并且也不一定会用到所有的数据,所以如果只是简单粗暴地把这些数据拷贝过来了,势必会造成大量的资源浪费。

    因此OS的设计者就不想让子进程直接地去拷贝数据,而是当程序运行的时候,当OS检测到子进程需要去修改父进程的数据的时候,他就会让子进程等一等,然后为他开辟一个新的空间把对应的数据拷贝过来再让他修改

     因此我们可以总结出,无论是代码还是数据,父子进程在前期都是共享的,只不过当OS一旦检测到子进程需要去对数据进行修改的时候,需要多少才会开多少空间,这就是数据层面的写时拷贝

5、父子进程都有了独立的task_struct,就可以独立地被CPU调度运行了 

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

父子的代码是共享的,所以return ret也是属于代码,因此父子进程各返回了一次! 

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

       原因是因为子进程要修改父进程的数据的时候,发生了写时拷贝,所以该数据其实有两份内容,然后因为进程的在运行的时候是具有独立性的,所以此时父进程和子进程通过if else 分流去执行共享的代码。 但是要注意的是,子进程被创建好之后,究竟是先运行子进程还是先运行父进程,其实是由调度器(因为CPU只有一个,所以他的作用就是在当前进程中选一个合适的放到CPU中,进程之间会竞争CPU资源,所以调度器会遵循着自己的一套原则来保证进程之间的公平性)去决定的!

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

       bash本身就是一个进程,当你输入相关指令的时候,他会为指令创建子进程,然后由子进程去执行对应的指令,这样即使子进程失败了也不会影响到bash——>目的是为了让bash可以专注于命令行解释的工作!!bash进程是在我们打开机器的时候就创建好的!

  

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

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

相关文章

Java反射:如何判断对象属性是否为static或final

哈喽,大家好,我是木头左! 在Java编程中,反射是一种强大的工具,允许在运行时检查类、接口、字段和方法的信息。通过反射,可以动态地创建对象、调用方法和访问字段,甚至可以修改私有字段的值。然而…

大模型:中国AI Agent应用研究报告2024

自2023年3月,以AutoGPT为代表的一系列技术框架的发布,Al Agent以其自主性和解决问题的能力,迅速获得科技圈各方讨论。并在之后一年多的时间中,陆续发布多项不同种类的技术框架。除了使用领域的探索之外,单智能体和多智…

2024华为OD统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++篇)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(E卷D卷A卷B卷C卷)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加…

大模型新书分享《大模型入门:技术原理与实战应用》(附PDF)

这本大模型书籍已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】 新书速递 书名: 大模型入门:技术原理与实战应用 ISBN: 9787115638816 作者: 程絮森,杨波&am…

产品经理的发现和成长

获取更多资料,见下图

原装N9000B信号分析仪keysight/N9000B,N9000A详情参数

是德Keysight N9000B CXA 信号分析仪,多点触控, 特征: 9 kHz 至 26.5 GHz 的宽频率范围以及高达 25 MHz 的分析带宽让您了解更多 为手动和自动化制造测试系统添加可靠的信号分析 执行基本测量,例如杂散搜索和失真分析 使用可选…

1658.将x减到0的最小操作数

题目 链接:leetcode链接 思路分析(滑动窗口) 题目要求从最左边或者最右边移除元素,需要思考两侧,这是比较麻烦的。 正难则反,我们逆向思维一下,最后剩余的元素是不是中间的连续区间&#xf…

人工智能 | Hugging Face 的应用

大纲 Hugging-Face 介绍 Hugging-Face 大语言模型 LLM 管理Transformers 机器学习框架文本生成推理 (TGI) Hugging Face Hugging-Face – 大语言模型界的 Github Hugging Face 专门开发用于构建机器学习应用的工具。该公司的代表产品是其为自然语言处理应用构建的 transfo…

网络编程(学习)2024.9.5

目录 网络协议头分析 MTU MSS 粘包和拆包 粘包 粘包原因 解决粘包 拆包 包头分析 以太网头 IP头 ​编辑 Tcp头 三次握手和四次挥手 三次握手 四次挥手 TCP可靠性的保证 1. 数据包顺序 2. 数据完整性 3.. 确认应答(ACK) 4. 重传机制…

springboot个性化大学生线上聊天交友系统

基于springbootvue实现的个性化大学生线上聊天交友系统 (源码L文ppt)4-017 4系统设计 4.1 软件功能模块设计 个性化大学生线上聊天交友分为两个模块,分别是管理员功能模块和用户功能模块。主要功能模块包括&#xff…

探索数据可视化的奥秘:Seaborn库的魔力

文章目录 探索数据可视化的奥秘:Seaborn库的魔力背景:为何选择Seaborn?Seaborn是什么?如何安装Seaborn?简单函数介绍与示例场景应用示例常见问题与解决方案总结 探索数据可视化的奥秘:Seaborn库的魔力 背景…

ApiOps Helper:本地代码智能扫描,API的注册管理自动化

APIOps Helper是什么 APIOps Helper是在IntelliJ IDEA平台上开发的插件,可以自动识别IDEA中Java项目的代码,从中扫描出API并自动生成OpenAPI规范文档。 用户可以选择将API导出为本地OpenAPI规范文档,或者将API同步到APIOps平台上进行API协同…

挑选展厅设计伙伴?这些考量点助你决策

如今,随着数字化技术的快速发展,内容展览展示行业已经脱变为一个汇聚创新与创意的展示空间,并成为企业、文旅等各行业竞相追捧的平台,因此,挑选一家专业的多媒体展厅设计公司显得尤为重要,但是,…

maestro复制

problem:ADE Explore的maestro 里保存了设置的仿真器Analyses和扫描参数 Design Variables,如果要新建一个当前的testbench副本,除了复制schematic还希望能把maestro一起复制过去。但是直接复制maestro后仿真的时候还是对原有的schemetic在仿…

能否使用PLC无线通信模块实现力控与FX5U无线以太网通信?

在实际系统中,车间里分布多台PLC,需要用上位机软件集中控制。通常所有设备距离在几十米到上百米不等。用户会选择以太网方式是因为传输速度有保障,而选择无线以太网方案是因为不想开挖电缆沟,或者布线不方便,不但施工麻…

AR远程协作与Web,视频会议,监控直播融合方案

​​随着全球化的加速和远程工作的普及,团队成员之间的沟通与协作变得更加重要。传统的远程协作方式存在诸多限制,如沟通不畅、信息共享困难等。AR技术以其独特的交互性和沉浸感,为远程协作提供了新的解决方案。 针对视频会议系统在特殊场景…

SprinBoot+Vue兼职发布平台的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…

开源AI市场情况概览:2024年的现状与发展

开源AI的快速发展 开源AI领域的显著进展:2024年,开源AI迅速发展,带动了生成式AI领域的重大创新。得益于GitHub和Hugging Face等平台,研究与开发者社区推出了许多具有突破性的项目,这些项目取得了令人瞩目的成果。 贡献者与项目增长:2023年,GitHub上的贡献者数量增加了…

大屏地图区域显示、复选框多选打点,自定义窗体信息(vue3+TS)

效果图: NPM 安装 Loader: npm i amap/amap-jsapi-loader --save 并设置 key 和安全密钥: import AMapLoader from amap/amap-jsapi-loader;//引入高德地图window._AMapSecurityConfig {securityJsCode: "「你申请的安全密钥」"…

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n 3 输出:5示例 2: 输…