设备体系架构搭建背景与构成

一、冯诺依曼体系结构

一台计算机笼统来讲,可以分为四个部分:

1.输入设备:键盘、磁盘、网卡、显卡、话筒、摄像头等 2.输出设备:显示器、磁盘、网卡、显卡、音箱等 3.存储器(内存) 4.运算器&&控制器(芯片即CPU)

由上面的磁盘、网卡、显卡同属于输入设备和输出设备,需要知道输入和输出设备并不是完全独立的工作的!

搭建设备体系架构的背景 设备体系结构_服务器


这里着重解释存储器(内存):

为什么要有内存?先引入一个概念:距离CPU越近的存储设备,运行效率越高!

搭建设备体系架构的背景 设备体系结构_网络_02

如果没有内存,那么当用户在外设输入数据时,CPU就只能直接从外设获取数据再进行处理。但是,外设处理数据的速度相对于CPU而言是非常慢的。而由“木桶原理”可知,

而所谓的IO(输入输出)是站在内存的角度而言的,把数据从输入设备存入内存的过程叫做input,把内存中的数据输出到输出设备的过程叫做output。 这里的IO是一个广义的概念,包括本地IO和网络IO。而区分两者的关键在于输入和输出设备(例如磁盘和网卡)。

关于冯诺依曼,必须强调几点:
•这里的存储器指的是内存
•不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)
•外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
任何外设,在数据层面,基本先和内存打交道。而CPU在数据层面上,也先和内存打交道。




二、操作系统


什么是操作系统?

答:OS是一款专门针对软硬件资源进行管理工作的软件。
补充:OS说白了就是存在磁盘上的软件,只有当它的软件数据和代码被加载到内存中开始工作时,才有意义。



为什么要有操作系统?

答:对下管理好软硬件资源;对上给用户提供稳定的、高效的、安全的运行环境。



操作系统是怎么进行管理的?

答:操作系统并不直接对计算机中的各种硬件进行决策管理,而是根据各种驱动程序中包含的各种硬件的数据进行分析,最终做出决策,再由驱动执行,从而达到管理效果的。(如图)
搭建设备体系架构的背景 设备体系结构_搭建设备体系架构的背景_03

操作系统如何管理进程?

答:先描述,再组织。
先用描述进程的结构体----PCB(进程控制块)对进程的各种属性进行描述,再用某一种数据结构(红黑树、AVL树、哈希表等)对各种属性数据进行存储。操作系统直接对相应的数据结构中的节点进行管理即可。
(这也是PCB存在的原因)




三、系统调用和库函数的概念

这里主要是解释上面那张图中用户操作接口和system call这两层。
在一台计算机上,用户并不是直接和操作系统进行交流的,而是通过调用各种接口间接地进行交流的。
总所周知,Linux是用C语言实现的,那么这里的接口实际上也就是C函数,可以理解为接口就是函数的一个高大上的名字而已。

•在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。 •系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。




四、进程

4.1基本概念

进程是什么?

答:加载到内存中的程序就叫做进程(大多数书本上给出的定义)。
担当分配系统资源(CPU时间,内存)的实体。(内核观点)

这里补充一点:操作系统中是可以由多个进程的,而操作系统对进城实现管理的过程可以简称为先描述,再组织(前面已经解释过了)。每个进程在被创建时,操作系统都要为进程创建PCB(进程控制模块)来保存进程所有的属性。

4.2描述进程–PCB


PCB是什么?

答:进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。课本上称之为PCB(process control block),Linux操作系统下的PCB是task_struct。


进程和程序的区别?

答:程序本质是存放在磁盘中的可执行程序,即.exe文件,是一个文件。而进程则是将程序加载到内存当中,并且由操作系统为其生成一个描述自身性质的数据结构(PCB),两者共同组成“进程”。

再补充一个概念:

CPU不能同时运行多个进程,而我们平常看到的多个进程能同时运行只是一个假象,而CPU是通过短时间内频繁切换正在运行的进程来制造出这种假象的。实际上,每个进程对应的PCB会排列起来形成一个CPU队列,这些PCB就会循环往复的不停交替出现在CPU中,以此实现”多个进程同时运行“。

故有了PCB,所有的进程管理任务与进程对应的程序毫无关系!与进程对应的由内核(操作系统)创建的PCB强相关!


task_ struct内容分类:

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

这些东西下文中一一讲解。

4.3查看进程

首先,我们先在Linux中创建一个.c文件和Makefile文件:
搭建设备体系架构的背景 设备体系结构_linux_04


内容如下:

搭建设备体系架构的背景 设备体系结构_linux_05

搭建设备体系架构的背景 设备体系结构_网络_06

接下来开始执行这个进程:
搭建设备体系架构的背景 设备体系结构_搭建设备体系架构的背景_07


内容开始在屏幕上输出

接下来执行下面指令:
搭建设备体系架构的背景 设备体系结构_网络_08

搭建设备体系架构的背景 设备体系结构_搭建设备体系架构的背景_09


这就是查看进程的指令,而结束进程只需Ctrl+c即可。


4.4task_ struct内容解释

标识符:

搭建设备体系架构的背景 设备体系结构_运维_10

搭建设备体系架构的背景 设备体系结构_linux_11


由上图可知,获取进程PID需要两个头文件,调用响相应函数,最后的返回值就是进程的PID。

对myproc.c稍作修改,内容如下:
搭建设备体系架构的背景 设备体系结构_运维_12


执行结果如下:
搭建设备体系架构的背景 设备体系结构_网络_13


而结束进程的方法不只有Ctrl+c这一种,还可以执行来结束进程。

而在上面图中,可以看到,一个进程还有自己的父进程,其父进程拥有对应的PPID,而获取PPID只需执行==getppid()==即可,如下:
搭建设备体系架构的背景 设备体系结构_服务器_14


退出码:在我们写C/C++程序时,main函数的最后总是要return 0,而这个0就是程序的退出码,不同的退出码代表的含义不同,这里不细说。

Linux中,查看进程退出码的指令为。(注意,这里查看的是上一个指令的退出码)搭建设备体系架构的背景 设备体系结构_运维_15


程序计数器:

这个概念其实跟汇编代码中的call指令有异曲同工之妙,这里就不细说了,感兴趣的伙伴可以浏览一下博主之前写的文章《不懂函数栈帧,你敢说你了解C语言吗?》

记账信息:

先补充一个概念:
操作系统中有一个调度模块,它负责比较均衡地为每一个进程分配CPU资源,以使得每一个进程都拥有相对均衡的运行时间。
而记账信息存储的就是每一个进程占用CPU的时间,以及每一次运行时运行的具体程度和产生的效果等信息。

上下文数据(很重要)

我们知道,当我们运行一段C代码时,里面会产生一些临时变量,而这些变量都会被保存在一个个的寄存器中,如下:
搭建设备体系架构的背景 设备体系结构_运维_16


同样的,当进程运行时,也会产生一些临时变量,它们也是被保存在寄存器中的。

还需要知道的是,当有多个进程需要执行时,操作系统会为每一个进程设置运行时间片,即每一个进程单次运行时间是固定的,当一段代码需要很长时间才能被执行完时,就需要多次占用CPU。

可是,CPU的寄存器只有一套!当多个进程不断切换时,寄存器中的信息就会被覆盖,当一个进程下一次运行时,之前运行得到的数据不就丢了吗?

为了解决这个问题,操作系统规定,当一个进程运行时间达到规定时间,但并没有运行完毕的时候,进程本身在离开CPU之前,就会将寄存器中自己产生的数据保存起来,当下一次运行时,再将这些数据放进寄存器中,以便自己可以接着运行,而不是从头再来。

通过上下文,我们也可以非常直观地感受到,进程在CPU中是来回切换的!

下面介绍另一种查看进程的方法:


搭建设备体系架构的背景 设备体系结构_运维_17

搭建设备体系架构的背景 设备体系结构_服务器_18


上图中的proc就是Linux中管理进程的目录,每一个进程运行时,都会在其中以自己的id为名字创建自己的目录。

搭建设备体系架构的背景 设备体系结构_服务器_19


来到这个进程的目录下,可以看到它所有的属性

其中cwd就是进程所在路径,默认是当前路径

而exe就是所谓的可执行程序。

4.5通过系统调用创建进程–fork初识

用代码创建进程的方式:

搭建设备体系架构的背景 设备体系结构_运维_20

搭建设备体系架构的背景 设备体系结构_linux_21

可以看到,代码中只有一个printf语句,但运行结果却有两个。

接下来看一个更神奇的现象:
搭建设备体系架构的背景 设备体系结构_服务器_22


我们知道,在一段C代码运行的时候,是不可能同时执行已经配对的if else语句的,但是这里却可以。第三个现象:
搭建设备体系架构的背景 设备体系结构_linux_23


可以看到,在一个while循环中打印出的两次Id并不相同,

这就表明,在fork之后,又创建了一个进程,两个进程分别在两个执行流中,因此可以分别执行if 和 else,也可以分别进入while循环!



如何理解fork创建进程?

1.在操作系统的角度,用命令行调用进程和自己在代码中用fork调用进程是没有区别的。 2.创建进程的本质就是操作系统中多了一套与进程相关的数据结构(task_struct)。并且默认情况下,创建的子进程或继承父进程的代码和数据。

前面提到,进程是由进程和进程相关的数据和代码组成的。那么创建了子进程之后,对数据会有什么处理呢?

答:进程的代码时共享的,是不可修改的。如果父子进程都没有要修改数据的操作,那么他们就共享一份数据。可如果有一方想要进行修改,操作系统为了保证进程的独立性,就会采用“写时拷贝”的方法,重新拷贝一份数据,这样两个进程就不会相互影响了。

创建子进程就是为了让它和父进程做同样的事情吗?

答:不是的,它们做的事是不同的。当fork创建子进程时,会分两种情况。创建失败时,返回值小于0;创建成功时,给父进程返回子进程的pid,给子进程返回0,如下:

搭建设备体系架构的背景 设备体系结构_服务器_24


所以,我们可以在一段程序中利用返回值不同,借助if else语句让父子进程做不一样的事



免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空