Linux---进程概念

目录

一、冯诺依曼体系结构

 二、操作系统

1.关于下三层的理解

2.关于上三层的理解

三、进程

1.进程(也叫做任务)对应的标识符---pid

 2.fork---用代码创建进程(系统接口)

1)初步认识一下fork 

2)fork函数的返回值

3)fork的原理

问题1: fork具体干了什么?

问题2: 为什么fork会有两个返回值?

问题3:为什么fork的两个返回值,给父进程返回子进程的pid,给子进程返回0?

问题4:fork之后,父子进程谁先运行?

问题5:如何理解同一个变量id,会有不同的值?


一、冯诺依曼体系结构

计算机都是由一个个的硬件组件组成

  • 输入设备:包括键盘、鼠标、扫描仪等
  • 中央处理器(CPU):含有运算器和控制器等
  • 输出设备:显示器、打印机等

注意:

  • 这里的存储器指的是内存
  • 不考虑缓存的情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入输出设备)
  • 外设要输入或者输出数据,也只能写入内存或者从内存中读取

总结:所有的设备都只能直接和内存打交道

上图是一个表示设备存储效率的金字塔图,根据木桶效应,我们会让效率相差不大的设备直接相连来保证相对高效的运行效率和相对较低的成本。

1.程序在被运行之前,得先加载到内存,为什么?程序(代码+数据)被运行,本质就是让CPU去执行,而CPU只和内存进行直接的数据交互,并且我们一般运行的程序都是exe文件,被存储在磁盘中,所以程序要被先加载到内存(体制结构决定)

2.如何理解网络信息之间的数据流动过程?(拿qq好友聊天举例)

 二、操作系统

1.是什么?是一款软件,进行软硬件资源管理的软件 (电脑开机先要打开操作系统)

2.为什么要有操作系统?操作系统将软硬件资源管理好(手段),给用户提供良好的(稳定,高效,安全)使用环境(目的)

3.怎么办?即如何实现

1.关于下三层的理解

  • 硬件部分是冯诺依曼体系结构。
  • 驱动程序---这个大家可能没怎么听过,但是我们都应该见过当插入U盘时,电脑会弹出一个U盘驱动程序启动类似的弹窗,那就是在运行驱动程序(不同的硬件有不同的驱动程序)。
  • 操作系统就是通过驱动程序来访问硬件资源的。

那么操作系统如何对软硬件资源进行管理?

这个其实可以类比现在学校的教务系统,学校对学生的管理本质是对学生的相关信息的管理,比方说,学校的校长并不了解每一个学生,但是他能对所有学生的学习情况了如指掌,为什么?因为他有你们每次考试的成绩数据,通过对这些数据的进行排序筛选等操作,他就能知道每个学生的学习情况,所以管理的本质是对数据进行管理

而如何记录学生相关数据,在计算机领域,显然就是用struct/class存放学生的基本信息等等,而对它们的管理,就是用相应的数据结构将数据连接组织起来,进行相应的增删查改的操作,所以总结一下就是六个字:先描述,在组织。

操作系统对硬件的管理也是如此,每个硬件都会有一个结构体对象用来描述该硬件的相关属性信息,再将它们用链表组织起来,这样对硬件的管理就变成了对链表的管理(当然也可能是其他的数据结构),所以一个硬件是否被管理,不在于它是否和电脑进行了物理连接,而在于操作系统中是否有一个结构体对象用来描述管理该硬件

2.关于上三层的理解

  • 用户---一般来讲指所有人,但是这里我们以开发者的视角来看待问题,因为操作系统如果对开发者都不提供服务,那么就没有所谓的软件应用给普通人使用
  • 用户调用接口和系统调用接口的存在是为了保护操作系统的安全

通过下三层的讲解,我们知道操作系统能访问硬件,那么我们用户能不能直接对操作系统进行操作以此来访问外设呢?

当然可以,但是我们不能保证用户的操作不会对操作系统造成影响甚至破坏,毕竟还是有恶意用户存在的,为此,操作系统提供了system call来防范用户的不合理的请求。


那么我们能不能绕过操作系统,直接对硬件进行访问呢?

这就有点类似于那种无人看管的图书馆,任何人都能进去借书,但是不做记录,因为没人管理,这座图书馆迟早出问题,同理,硬件也需要操作系统来进行统一的管理


那么为什么有用户操作接口呢?

因为系统接口用起来比较麻烦,不是所有人都能很好的使用系统接口,所以在system call之上还有用户操作接口,来简化用户的操作

外壳程序在Linux中是shell,在windows中是图形化界面。拿windows系统举个例子,当我们双击图标打开文件的时候,本质是调用系统接口打开文件,打开不同的文件要传的参数也不同,如果让你去选,你愿意双击还是敲系统接口,显然我们都喜欢双击。

各个语言的lib(标注库)也是如此,拿C语言举例,C标准库中的函数有很大一部分都是对系统接口进行了封装实现的,比如printf打印字符串到显示器,对于硬件的访问都是要经过操作系统的,所以别看我们只写了一行打印语句,底层还是封装的系统调用接口帮助我们实现的。库的实现,提高了开发的效率

三、进程

什么是进程?进程是正在执行的程序。

我们如何理解这句话?

进程=可执行程序+内核数据结构(pcb),对于"正在执行"的理解其实就是进程会在不同的状态之间切换,比如我们打开了很多进程,但不是每个进程都在一直被运行,而是用到它的时候就让它运行,不用的时候就让它等待(当然还有其他状态),看起来进程好像是动态的,本质还是对内核数据结构的操作


Linux中的PCB是struct task_struct{}

tast_struct中有哪些内容?

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

1.进程(也叫做任务)对应的标识符---pid

可以看见mytest的进程pid为22385,当然这个pid是会变化的,每次运行都不一样,这跟我们去排队,然后中途有事离开,再回来时需要重新排队是一个道理。

(感兴趣的可以用man ps去看看ps命令的介绍和其他选项)

(重新在运行程序后ps命令的截图) 

ppid是进程的父进程,mytest的父进程是bash命令行,bash命令行是一直在运行的,所以id不变 

Linux中启动进程的两种方式:1.手动输入命令行启动  2.通过代码创建进程启动

进程的启动本质是创建进程,一般通过父进程创建(如上,我们通过bash命令行解释器这个父进程创建mytest这个子进程),所以进程间有一种父子关系。

这里介绍获取pid和ppid的函数

除了ps命令,我们还可以通过 /proc 这个目录来查看进程的信息。

蓝色的数字就是进程的pid,我们可以运行一下自己的进程看看

当我们运行程序时,就会再/proc目录中创建相关的目录记录该进程信息,当我们结束进程时,对应的目录就会被删除。所以 /proc 是动态的目录结构,存放所有存在的进程,目录的名称,就是以这个进程的id命名的。


下面我们来看看这个目录中存放了些什么

这些文件都是进程的相关信息,我们暂不关心,我们主要看被框里来的两个。

第二个被框起来的部分是该程序在磁盘上的位置,也就是说,一个进程能找到自己的可执行程序。

在上面的操作中,我们先运行mytest,然后将mytest从磁盘上删掉。可以从该进程的目录下看到该进程知道自己被删除,但是却还在正常运行,为什么?在之前我们就说过,进程的创建要先将程序加载到内存,所以我们运行的是内存中的mytest程序,磁盘上的mytest删除并不会影响内存中的程序运行。


cwd---当前目录,这个大家在学C语言的文件操作的时候,应该就听过这个概念

//fopen函数的第一个参数如果传的是相对路径,就会在该路径前面加上cwd
//这就是为什么我们创建的文件一般都在项目所在的目录下,
//一般我们默认的当前目录都是进程启动所处的路径
fopen("test.txt","w");

当然这个当前路径是可以改变的,用下面这个函数

int chdir(const char *path);

 2.fork---用代码创建进程(系统接口)

启动进程,本质是在系统中创建一个进程,操作系统管理的进程多一个,而进程=可执行程序+内核数据结构(task_struct对象),所以创建进程,就是申请内存空间保存可执行程序+task_struct对象,并将tast_struct对象添加到进程队列中。

1)初步认识一下fork 

fork可以用来创建进程,如下 

第二个打印语句被执行了两次,且它们pid不同,那么我们来看看这两个进程的ppid分别是什么。

现象:mytest的父进程是bash,新创建的进程的父进程为mytest,所以fork函数用来创建子进程,且子进程只执行fork之后的语句,前面的语句不执行

(可以推断出bash命令行创建子进程用的就是fork函数)

2)fork函数的返回值

fork函数的返回值不同,这很难理解,但是我们根据现象可知,在父进程中返回子进程的pid,在子进程中返回0,当然如果创建进程失败,返回-1

这里要说明一下创建子进程的意义是什么,创建子进程是为了辅助父进程完成工作,而不是为了和父进程执行一样的操作,所以我们一般是这样用fork的

用if-else语句将父子进程要做的事情分流,所以我们需要有两个返回值来分辨这两个进程

3)fork的原理

在上面的演示,其实我们还有很多问题没有讲清楚

  1. fork具体干了什么?
  2. 为什么fork会有两个返回值?
  3. 为什么fork的两个返回值,给父进程返回子进程的pid,给子进程返回0?
  4. fork之后,父子进程谁先运行?
  5. 如何理解同一个变量id,会有不同的值?
问题1: fork具体干了什么?


问题2: 为什么fork会有两个返回值?

在之前我们就说过fork是用来创建子进程的,那么fork创建子进程实在最后一句return语句之后才彻底完成的吗?显然不是,创建子进程的工作一定在return之前就已经完成了,所以在return之前,父子进程就已经开始共享数据和代码执行相关语句,当然fork的return也在其中,所以fork会有两个返回值


问题3:为什么fork的两个返回值,给父进程返回子进程的pid,给子进程返回0?

因为一个父进程可以创建多个子进程,而一个子进程只能有一个父进程,所以父进程需要知道子进程的id来分辨子进程,而子进程不需要,因为它只有一个父进程


问题4:fork之后,父子进程谁先运行?

这个是不确定的,当创建了子进程后,父子进程都需要在运行队列中排队,哪一个进程的pcb先被选择调度,哪个进程就先运行(具体由pcb中的调度信息和调度器算法共同决定,可以理解为由操作系统决定)


问题5:如何理解同一个变量id,会有不同的值?

当我们终止子进程/父进程时,会不会影响另一个进程的运行?

所以任何一个进程都具有独立性,但是我们知道父子进程的代码和数据是共享的,它怎么保证互不影响呢?首先代码是只读的,不可修改,那么数据呢?

在父子进程运行的过程中,我们都会用到数据,如果某些数据会被两个进程同时影响会导致代码逻辑出现问题,所以操作系统会让进程的数据各自"私有",当然这个不是说就完全拷贝一份给子进程,而是通过写时拷贝(就是在写入时才会出现拷贝)实现的,这样会减少空间浪费。

而fork函数的返回值给id这个变量,本质就是数据写入,会出现写实拷贝,所以id会有两个值

但其实我们还不能完全解释这个现象

看上图,我们会发现id这个变量的地址是一样的,但是一样的地址却有两个不同的值,这不可能,所以我们能确定这个地址不是真正的物理地址!!!(具体在进程空间再讲)

未完待续……

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

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

相关文章

虚拟机性能监控、故障处理工具

虚拟机性能监控、故障处理工具 二、基础故障处理工具4.2.1 jps:虚拟机进程状况工具4.2.2 jstat:虚拟机统计信息监视工具4.2.3 jinfo:Java配置信息工具4.2.4 jmap:java内存映像工具4.2.5 jhat:虚拟机堆转储快照分析工具4.2.6 jstack:Java堆栈跟踪工具4.2.…

四舍五入浮点数

1.题目如下: 2.方法一: 直接取出小数部分第一位来判断。 1. 先乘以10。 2. 强制类型转换为整型,去掉小数部分。 3. 再模10,相当于取出原数的小数第一位。 代码实现: int way1(double n) {int a (int)(n * 10);int b…

后端开发——统一处理异常Spring MVC机制

一、Spring MVC的统一处理异常机制 在Spring MVC中,存在统一处理异常的机制, 具体表现为:无论是哪个处理请求的过程中出现异常,每种类型的异常只需要编写一段处理异常的代码即可! 统一处理异常的核心是定义处理异常的…

【k8s】使用Finalizers控制k8s资源删除

文章目录 词汇表基本删除操作Finalizers是什么?Owner References又是什么?强制删除命名空间参考 你有没有在使用k8s过程中遇到过这种情况: 通过kubectl delete指令删除一些资源时,一直处于Terminating状态。 这是为什么呢? 本文将…

智能优化算法应用:基于静电放电算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于静电放电算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于静电放电算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.静电放电算法4.实验参数设定5.算法结果6.…

FME之FeatureReader转换器按表格内容读取矢量数据

问题:平时会遇到只用某个大数据里某小部分数据参与下一步数据处理,此时我们会用到FeatureReader转换器,一般是通过空间关系(相交、包含)来读取相应涉及的图斑矢量,但就有一个问题,加入你的启动器…

计算机视觉(P2)-计算机视觉任务和应用

一、说明 在本文中,我们将探讨主要的计算机视觉任务以及每个任务最流行的应用程序。 二、图像内容分类 2.1. 图像分类 图像分类是计算机视觉领域的主要任务之一[1]。在该任务中,经过训练的模型根据预定义的类集为图像分配特定的类。下图是著名的CIFAR…

格式化Echarts的X轴显示,设置显示间隔

业务需求:x轴间隔4个显示,并且末尾显示23时 x轴为写死的0时-23时,使用Array.from data: Array.from({ length: 24 }).map((_, i) > ${i}时) 需要在axisLabel 里使用 interval: 0, // 强制显示所有刻度标签,然后通过 formatter …

分面中添加不同表格

简介 关于分面的推文,小编根据实际科研需求,已经分享了很多技巧。例如: 分面一页多图 基于分面的面积图绘制 分面中的细节调整汇总 分面中添加不同的直线 基于分面的折线图绘制 最近遇到了另一个需求:在分面中添加不同的表…

计算机网络(四)

九、网络安全 (一)什么是网络安全? A、网络安全状况 分布式反射攻击逐渐成为拒绝攻击的重要形式 涉及重要行业和政府部门的高危漏洞事件增多。 基础应用和通用软硬件漏洞风险凸显(“心脏出血”,“破壳”等&#x…

Content-Type是什么

目录 Content-Type是什么 获取方式 设置方式 常见类型 application/x-www-form-urlencoded multipart/form-data application/json text/xml text/html text/plain Content-Type是什么 Content-Type出现在请求标头和响应标头中,意思是内容类型&#xff0…

LOF基金跟股票一样吗?

LOF基金,全称为"上市型开放式基金",是一种可以在上海证券交易所认购、申购、赎回及交易的开放式证券投资基金。投资者可以通过上海证券交易所场内证券经营机构或场外基金销售机构进行认购、申购和赎回基金份额。 LOF基金的特点是既可以像股票…

论文阅读——GroupViT

GroupViT: Semantic Segmentation Emerges from Text Supervision 一、思想 把Transformer层分为多个组阶段grouping stages,每个stage通过自注意力机制学习一组tokens,然后使用学习到的组tokens通过分组模块Grouping Block融合相似的图片tokens。通过这…

【docker 】基于Dockerfile创建镜像

Dockerfile文档 Dockerfile文档地址 Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。 DockerFile 可以说是一种可以被 Docker 程序解释的脚本,DockerFile 是由一条条的命令组成的,每条命令对应 …

LCR 181. 字符串中的单词反转

解题思路: class Solution {public String reverseMessage(String message) {message message.trim(); // 删除首尾空格int j message.length() - 1, i j;StringBuilder res new StringBuilder();while (i > 0) {while (i >…

极智一周 | 两系列汇总、MI300X、H100、特供芯片、GPT-4、火灾检测、酷睿Ultra And so on

欢迎关注我的公众号 [极智视界],获取我的更多技术分享 大家好,我是极智视界,带来本周的 [极智一周],关键词:两系列汇总、MI300X、H100、特供芯片、GPT-4、火灾检测、酷睿Ultra And so on。 邀您加入我的知识星球「极智…

数据分析为何要学统计学(2)——如何估计总体概率分布

明确总体的概率分布类型及参数是进行数据分析的基础,这项工作称为分布推断与参数估计。在总体分布及其参数不明确的情况下,我们可以利用手头掌握的样本来完成这项工作。具体过程由以下步骤组成。 第一步,样本统计特性直观估计 我们采用Seab…

在ViewPager下面加圆点指示(使用selector方式)

前面讲了如何使用ViewPager来做多个可滑动的页面。今天在页面的下面加上一排小圆点,用于指示当前在第几页。效果如下(请忽略颜色和图案): 一、产生一个小圆点的视图 1、在drawable下产生一个选中和不选中颜色不同的小圆点形状&am…

1- Electron 创建项目、初始化项目

Electron官网 Build cross-platform desktop apps with JavaScript, HTML, and CSS | Electron Electron 初始化 初始化项目 - 构造package.json npm init -y 安装Electron模块包 npm i electron -D // 注意!如果报错查看node包是否太高 配置启动脚本 {&quo…

SQL、Jdbc、JdbcTemplate、Mybatics

数据库:查询(show、select)、创建(create)、使用(use)、删除(drop)数据库 表:创建(【字段】约束、数据类型)、查询、修改(alter *add)、删除 DML:增加(inse…