| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 【Linux】四、Linux 进程概念(上篇)| 冯诺依曼体系结构| 操作系统| 进程 |子进程fork -> 正文阅读 |
|
[系统运维]【Linux】四、Linux 进程概念(上篇)| 冯诺依曼体系结构| 操作系统| 进程 |子进程fork |
目录 前言本节主要学习以下内容:
一、冯诺依曼体系结构1.1 冯诺依曼体系结构是什么????????冯·诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。数学家冯·诺依曼提出了计算机制造的三个基本原则,即采用二进制逻辑、程序存储执行以及计算机由五个部分组成(运算器、控制器、存储器、输入设备、输出设备),这套理论被称为冯·诺依曼体系结构。 ????????我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。 冯诺依曼体系结构如图: ???
1.2 冯诺依曼体系结构为什么这么设计1.2.1 思考有没有想过冯诺依曼体系结构为什么不这么设计?而是设计多了一个储存器,也就是内存? 想要了解清楚,请往下阅读! 1.2.2 了解一下计算机的存储分级????????在此之前先了解一下计算机的存储分级,其中寄存器离 CPU 最近;L1、L2、L3 是对应的三级缓存;主存通常指的是内存;本地存储(硬盘)和远程储存通常指的是外设。 储存器的特点:离 CPU 更近的,存储容量更小、速度更快、成本更高,如主存往上的;离 CPU 更远的,则相反,如本地磁盘。如上图,它们呈现如金字塔形状。 1.2.3 解释我们对木桶原理都有了解,要去衡量木桶能装多少水,并不是由最高的木片决定的,而是由最短的木片决定的。 ?而我们的中央处理器CPU 就是如木桶原理一样。 假设 CPU 直接访问磁盘,也就是如下图,那么它的效率可太低了。假设这里 CPU 是速率是纳秒级别的,则磁盘是速率毫秒级别的,这两个之间的速率就相差了 100 万倍,(1s=10^3ms(毫秒)=10^6μs(微秒)=10^9ns(纳秒)),当一个快的设备和一个慢的设备一起协同时,最终的效率肯定是以慢的设备为主。所以硬盘的存在严重拖慢了 CPU 的速率,整个计算机体系的效率就一定会被拖累。 所以,这时候就需要有一个介质来联通 CPU 和 硬盘之间的通道,这个介质就是冯诺依曼体系结构中的存储器,也就是我们的内存。这下理解冯诺依曼体系结构为什么这么设计了吧。 有了内存的存在,计算机的整体效率就会大大的提高。依旧假设这里 CPU 是速率是纳秒级别的,则磁盘是速率毫秒级别的(1s=10^3ms(毫秒)=10^6μs(微秒)=10^9ns(纳秒),CPU 与内存的速率就只是相差了 1000 倍左右,内存与硬盘之间的速率也是差了 1000 倍左右,CPU 只与内存进行交互,不与外设(磁盘之类)进行交互,这里计算机的短板就不再是磁盘了,所以计算机的整体速率就会大大提升。 ----------------我是分割线--------------- 那有人又问了,既然这个存储器(内存)这么好,为什么不把计算机的磁盘内存全部换成内存或者是寄存器? 首先明确内存是一直需要通电的,没有电的供应它里面存储的所有数据都会丢失,而像磁盘之类的没电了数据依旧存储在磁盘里面,放上个十年也没有事。第二,要明白内存是要钱的,越靠近 CPU 的内存价格越昂贵。假设把计算机的磁盘内存全部换成内存或寄存器,从技术角度可以的,但是生产出来的计算机就会特别昂贵,十几万起步那种,这种计算机的价格普通人接受不了,这种产品就不会进行大量的传播。要知道:凡是被广泛传播的产品,它的价格一定是便宜的,质量是可以的,价格普通人可以接受。就好比几千万的车,你身边的人为什么不开呢?原因就是它价格昂贵,普通人接受不了,那么这种产品就不会被大范围的传播。 而冯诺依曼的这种体系结构通过添加一块内存,几乎可以达到和你全部换成内存的计算机速率一致,还能以较低的成本生产出来,这样的产品就会被世界范围内的人所接受。换句话说,就是因为它便宜,你才愿意用它、买得起它,冯诺依曼体系结构就是这个道理。 1.3?往下要明确几点
这里暂且简单认识,后面会详细讲。 关于冯诺依曼,必须强调几点:
1.4?冯诺依曼实例????????对冯诺依曼的理解,不能停留在概念上,要深入到对软件数据流理解上,请解释,从你登录上qq开始和某位朋友聊天开始,数据的流动过程。 从你打开窗口,开始给他发消息,到他的到消息之后的数据流动过程。如果是在qq上发送文件呢?(注意这里的计算机都遵循冯 ? 诺依曼体系结构,且这里不谈网络,不考虑细节,只谈数据流向) (1)假设你给qq朋友发送 hello,你是发送数据的一端,请解释数据是如何流向的?(不考虑细节,只谈数据流向) 解释:你此时从键盘上输入 “hello”,此时 “hello” 会回显到你的显示器上(不考虑细节),此时“hello” 会储存在寄存器(内存)中,然后内存传给 CPU ,经过 CPU 处理写回你的内存里,然后由内存刷新到外设(这里不在是磁盘,而是网卡),然后上传到网络上,经过网络你朋友的设备中的输入设备(网卡)先识别到这条消息,传到内存,内存再传给 CPU 计算,计算完成写回内存里,再由内存刷新到你朋友的输出设备(这里是显示屏),到这一条数据的流向就完成了。 (2)发送的是文件呢? 文件依旧是数据,与上面类似,不在解释。计算机的数据流向基本都是这样的,进行类比即可理解 (3)数据为什么这么流向? 是由你的硬件和冯诺依曼体系结构决定的? ?----------------我是分割线--------------- 二、操作系统(Operating System)2.1?操作系统概念任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
2.2 为什么要有操作系统
总的来说就一句话:对下管理好所有的软硬件,对上给用户提供一个稳定高效的运行环境。 2.3 计算机体系及操作系统的定位计算机体系: ?操作系统的定位:
那问题来了,什么是“管理”呢,如何理解“管理”?? ?----------------我是分割线--------------- 2.4?如何理解 "管理"2.4.1 学校例子(用于理解概念)????????现实中我们做事情无非是 a、做决策 b、做执行。比如你想吃一碗粉,首先你进行做决策去哪家餐馆,做了决定后你走向你想去的餐馆,走这个过程就是做执行。 假设在学校里一般有这三种角色(进行了简化)
这里还要明白一点:管理者和被管理者可以不直接沟通。比如,你的大学校长(管理者)没有和你直接见面,却可以随时管理你。 比如拿奖学金与否、挂科与否,表现如何,学生信息如何,校长都可以随时管理。比如说评选奖学金,校长在系统中筛选好某系某级综合成绩排名前 3 的学生来发奖学金,这时校长把 3 位同学的辅导员叫过来,并要求开一个表彰大会来奖励 3 位同学,然后辅导员就开始着手执行工作。再比如,校长要开除一名学生,则校长只要知道这个学生挂了多少科,有没有达到学校的标准,没达到标准就可以开除他了,开除就找辅导员执行这项工作。 校长为什么能管理你,为什么连你的面都没见过就能管理你,因为你的个人信息在学校的系统里面,也就是说校长管理学生的本质是通过 “ 数据 ” 来进行管理的。
----------------我是分割线--------------- 理解了上面,那又有一个问题来了,校长是如何拿到数据并对它进行管理呢 ? 假设只有一个学生,这个学生产生的各种数据,校长都可以随便对这些进行管理。 那如果有5万学生呢,这些学生每天产生的数据全部扔给校长,校长又怎么管理呢?直接对数据管理明显就是不可能,这种无序的数据是没有意义的。校长就定义一个结构体,这个结构体包含了一名学生的所有信息,有多少学生就定义这个结构体数组有多大。
这里我解释有点绕,水平有限,hhh...? ?----------------我是分割线--------------- 2.4.2 银行例子(类比系统)?假设有一个银行系统,类比如上。 银行工作的时候,整个封闭的银行就放出了几个柜台,供业务工作使用,要办理业务的人来了就到柜台去办理。那为什么银行给你提供服务是以柜台窗口的形式进行?为什么柜台前还有一块很厚的玻璃?答案是:不相信你呗。这也说明银行这套体系预先把你当坏人,把所有人都预先当做坏人,有这种保护措施同时也将银行的风险降到了最低,还能给银行提供了一个稳定安全的服务。 进行类比,如果计算机把操作系统中的各种东西(内存管理,文件系统,进程管理,驱动管理...等等)暴露给用户,就好比银行门户大开,工作人员没有玻璃阻隔跟你面对面交流,银行的钱直接就放到桌面上,上层的人(客户)想拿钱就随时拿,这就给银行带来很大危险(随时遭受抢劫..)。这说明不把操作系统暴露给用户就是为了保证操作系统的安全性,操作系统也把所有人当做坏人。 银行用户有需求想办理业务,银行提供各种服务,用户就直接去柜台办理。类比,计算机用户也需要办理业务,操作系统也需要给用户提供各种服务,提供的服务也是通过柜台来办理,这里的柜台就是各种系统接口(system call) 这里的各种系统接口就是操作系统提供的各种函数。就如LInux是用C语言写的,系统接口的本质:就是用C语言提供的函数(操作系统相关的,不是我们C语言的库函数)。我们把这种系统接口(system call)就叫做系统调用。 到此结束,总结一下:
2.5?系统调用和库函数概念(总结)
----------------我是分割线--------------- ?三、进程(process)3.1?基本概念在Windows下我们查看进程在任务管理器中
操作系统里面是存在大量进程的,也可以同时加载多个进程,Linux 也是如此。那存在这些大量的进程要不要被管理呢?答案是必须的 Linux 是如何管理大量的进程的呢?
?程序加载到了内存,操作系统该怎么调度呢?操作系统怎么知道哪个执行完了,怎么知道哪个的优先级需要调整,怎么知道哪个执行到一半需要切换?操作系统完全不知道。 操作系统目前没有能力管理这些进程,因为这些加载进来的程序只有代码和数据,没有任何描述自身结构,所以操作系统需要对进程管理就需要对进程先描述,再组织管理。
什么是属性呢? C++中的类一切皆对象,C语言的?struct 封装,C/C++对一个事物的封装一定包含了该事物的所有属性。 我们人认识世界,是通过“属性”来认识的,比如我对一个事物进行描述:有一个事物他会汪汪叫,会帮人们看家护院,这时我们潜意识就会想到狗,是不是呢?只要是被人认识的东西,就一定会被人抽象换成各种属性,然后就能用计算机语言描述出来。所以PCB这个结构体一定包含了进程所有的属性 那问题又来了,属性是数据吗?
属性和程序内的代码和数据有关系吗?
到最后解释一下,什么是进程呢?
为什么存在PCB结构体?
什么是PCB结构体? 没有谈,下面解释? ?----------------我是分割线--------------- 3.2?描述进程 - PCB什么是PCB? 课本上称之为PCB(process control block),PCB就是一个结构体,不同的操作系统中PCB的名字叫法不同。
task_struct 跟PCB的关系就跟王婆和媒婆的关系一样,王婆是一个具体的媒婆,task_struct 也是一个具体的PCB结构体 3.2.1?task_struct - PCB的一种
?3.2.2?task_ struct内容分类这里的简单了解,先有个概念,后面详细讲
3.3 组织进程
?----------------我是分割线---------------?? 3.4 查看进程默认查看自己终端的进程
?查看系统所有的进程
这里我写了个死循环,方便观察进程
运行程序 ?查看我们想要查看的程序
把头部标签带上
?其中,PID就是进程ID(process ID),其他后面解释。 ?那有人好奇了,你说 10983 是 mytest 的进程ID,那下面的13696 进程又是什么? 别忘了你执行了 grep 命令,一个命令的执行也是一个进程,所以 13696 进程是 grep 命令的进程ID 如果结束 mytest 这个进程,当然你查就查不到啦 ?进程的信息可以通过 /proc 系统文件夹查看,把所有进程以文件系统的形式展示
?查看单个进程详细信息
?其中的 cwd 为当前工作目录(每个进程的都会有一个属性,来保存自己所在的工作路径),exe 则是该进程的可执行程序所处的位置 ??查看单个进程简略信息(所有属性),上面是详细的,这里简略
?要查看更多 ps 选项用法,直接 man 就行了
?----------------我是分割线---------------? 3.5?通过系统调用获取进程标示符3.5.1?查看进程ID(PID)通过系统调用获取 PID 标示符为:getpid man查看一下详细信息,其中的头文件与C语言无关,pid_t 是无符号整数,相当于用于定义一个变量的类型,直接使用它即可(如:定义一个变量id,pit_t? id = 0) ?修改代码,通过系统调用查看pid
运行一下,可以查看PID ?进行比对,命令行与系统调用的PID一样? 除了在自己的终端关闭进程,在别的终端也可以杀掉进程,命令 kill,-9为发送九号信号(暂且不讲,后面学)
回车后,就发现右边终端的进程被杀掉了? ?每个进程都会有自己独立的 PID,不会出现重复的PID ?----------------我是分割线---------------? 3.5.2?查看父进程ID(PPID)进程是有父子关系的,PID 的父进程叫做 PPID ?通过系统调用获取父进程ID标示符为:getppid 同样 man查看一下详细信息,其中的头文件与C语言无关,pid_t 是无符号整数,直接使用它即可 ??修改代码,通过系统调用查看ppid ?进行比对,一致
?这里我在自己的终端杀掉这个bash终端它直接强制退出了,我就无法演示了。如果在另一个终端杀掉自己终端的bash,之后自己终端所有命令都无法执行。 ??----------------我是分割线---------------? 四、通过系统调用创建进程 - fork 初识4.1 创建子进程 - fork?man 查看一下 fork 函数,头文件是<unistd.h>,fork的作用是创建一个子进程(child process) ?fork 的返回值有两个
?先记住 fork 有两个返回值 ???----------------我是分割线---------------? 4.2 测试 fork测试代码
把 fork 注释掉,运行结果,只执行一次 printf? 不注释 fork ,运行结果,?printf 被执行了两次? ?打印了两次,这是为什么?它只有一条语句,可是在 fork 之后被执行了两次,这是怎么回事?
再进行测试
结果打印了两次,一个变量怎么可能是两个值?
在以前,学C/C++的时候,我们没见过两个死循环同时执行,也没见过 if 和 else 同时执行 测试代码
fork 之后有两个不同的执行流?,两个进程的返回值不同从而决定了执行不同条件的代码,子进程的ppid 是父进程的 PID ?这里的现象仅仅是因为使用 fork 产生的特殊情况 ????----------------我是分割线---------------? 4.3 一个感性的问题fork 为什么给子进程返回 0,给父进程返回子进程的PID? 这里没有官方的解释,这里只给出这个问题的一个感性认识。 一个子进程永远只有一个父进程,但父进程可以拥有多个子进程。比如,一个孩子只有一个父亲,而父亲可以有多个孩子。 进程多了就要有进程的标识符,没有事不行的。就好比一个父亲他有三个孩子,父亲想叫其中的一个孩子,得叫孩子的名字吧,不叫孩子怎么知道叫哪一个孩子,总不能说:孩子,你过来一下。这样叫哪知道是哪一个,同比进程也是如此,得有一个认得出你的标识符。给子进程返回 0,给父进程返回子进程的PID就是类似情况 ?????----------------我是分割线---------------? 4.4 为什么会有两个返回值?创建子进程也新建了一个 task_struct 结构体,这个 task_struct 以父进程的task_struct 为模范创建,但又不完全相同。 ?CPU 想要运行一个进程,要经过复杂的数据结构和算法,形成一个运行队列,从运行队列里面选择进程执行。 CPU 运行一个进程,本质是从 task_struct 形成的队列中挑选一个task_struct 来执行它的代码。 一个函数已经准备 return,核心代码已经执行完了。那也说明子进程也已经加载到运行队列里面了,CPU可以随时调度,父进程与子进程已经同时存在运行队列里面了,父进程执行完成子进程也差不多完成了,父子各自执行自己的返回值,父进程和子进程执行完当然就有两个返回值了。 返回两次不代表一个变量会记录两个值 ????----------------我是分割线---------------? 父子进程被创建出来,哪一个程序先运行? ?答案不一定,都有可能,由操作系统调度器决定 到这里只 fork 的基本概念就差不多完成了 ????----------------我是分割线---------------? 文章先到这,下篇即将更新 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 9:56:23- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |