操作系统(三)

前言

操作系统里面有两个非常重要的图像,一个是多进程图像,另外一个就是文件管理图像。这一篇博客来和大家探讨一下什么是多进程图像,以及操作系统是如何支持多进程图像的。

多进程操作系统的由来

多进程图像对操作系统非常重要,是操作系统的核心部分,明白了它之后对于操作系统就明白了一大部分。

那么多进程图像是怎么想出来的呢?
操作系统的核心就是管理硬件,CPU是计算机的核心硬件,操作系统就是在管理cpu的时候想出了多进程图像,并且通过多进程图像将cpu管理好了,CPU管理好了,其他硬件自然带动起来了,所以说多进程图像是操作系统的核心图像。

cpu管理的直观想法:

管理CPU,首先使用cpu,管理它就是要更加高效的使用它。cpu是怎么用的呢?

cpu是如何工作的

CPU的工作原理:如果pc指针是200,那么cpu就是把200放在地址总线上面,然后内存知道地址总线上面的值是200,就把200这个地址对应的指令通过数据总线发给cpu,然后cpu执行指令,pc指针自动加一,如此往复。

从这里可以看出,只要给cpu一个初值就可以工作了。,因为pc指针会自动加加的,

这么一直执行有没有什么问题呢?
功能上是没有问题的,因为无论有多少道程序,只要计算机不死机总能执行完;但是在性能上呢?我们都知道程序并不都是计算程序的,有些程序是要访问io的,如果是都是计算的程序,那么cpu一直在使用,利用率为100%,但如果是访问io的程序呢?在访问io时,cpu是处于空闲状态的,如果按照刚才那种执行方式在访问io的时候,cpu只能干等着,这样就降低了cpu的使用效率了。实际上,这对于cpu的效率影响是非常大的,cpu访问一次io用的时间可能可以让cpu执行十万次计算指令了,毕竟电子设备和机械设备的速度差了很多个数量级。

有问题存在就会有人去想解决方法。正如“你为什么要去登珠穆朗玛峰?因为它就在那里”一样。这个问题就像你泡茶的时候,在等水开的那段时间你会一直盯着水看吗?肯定不会,因为你看不看对结果没有影响,水并不会因为你在旁边看而缩短开的时间。

于是有人提出一个解决方法,如果程序A在访问io,那么就趁这段时间去执行程序B,等程序A的io访问完了之后再接着执行程序A,这样就会缩短程序总的执行时间;cpu的利用率也就自然而然的上来了。即“同时”执行多道程序。

“多道程序、交替执行”是提高cpu效率的一个好办法。但是如何实现呢?

在一个cpu上面交替执行多个程序称为:并发。如何实现并发?程序A在执行的时候如果碰见io指令就跳到程序B去执行,这个可以通过修改PC指针来实现,等程序A的io执行完了再跳回来也是通过修改PC指针就可以实现,看起来好像很容易实现,但是真的是这样吗?看下面一个例子:
在这里插入图片描述
如果只执行程序1,那么当add ax,bx 执行完之后,ax里面的值是3,但是现在如果执行完

mov ax,1
mov bx,2

   
  • 1
  • 2

之后跳到

mov ax,100
mov bx,200

   
  • 1
  • 2

再跳到add ax,bx;那么ax中的值就是300,很明显不符合程序1的逻辑。因此为了解决这个问题,操作系统给每个运行中的程序提供一个存放信息的结构:PCB(进程控制块),这可不是PCB线路板哦;PCB是一种数据结构,存放的是程序跳转时当前运行程序的信息,比如上面那个例子,在mov bx,2执行完了之后,ax,bx的值、下一条指令的执行地址都会被存在PCB中,等再次执行程序1的时候ax、bx的值仍然是1和2.

注意上面那段话中出现了一个概念:运行中的程序;这是什么意思,如果程序在磁盘中没有运行,那么这种程序叫静态程序,如果一个程序正在运行,那么就叫运行中的程序。他们有什么不一样呢?

  1. 最直观的一个在运行,一个没在运行;
  2. 运行中的程序有开始和结束,因为不一定会一直运行它;
  3. 运行中的程序还有一个PCB用来存储当前程序的运行状态,等等

既然这种运行中的程序与静态程序有这么多不一样地方地方,那么肯定需要一个概念来描述它,那就是“进程”。

小结一下

如何让cpu工作?给它一个进程就好了;如何让cpu高效率的工作?让它“同时”执行多个程序就好了。

操作系统是如何支持多进程图像的

多进程给上层用户的感觉就是:同时启动了多少个进程
操作系统只需要把这些进程记录好,按照合理次序推进,让用户感觉这几个进程同时在运行。

前面说过,main.c文件中有这样两行:

if (!fork())
{init();}

   
  • 1
  • 2

这个其实就是创建了第一个进程。就是创建第一个进程,在init中创建了shell,shell对应windows就是启动了windows桌面。在shell中有如下一段代码(init()中):

int main(int argc,char*argv[])
{
	while(1)
	{
		scanf("%s", cmd);
		if(!fork())
		{
			exec(cmd);
		}
		wait();
	}
}

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

大意就是:等待用户输入一个命令,然后创建一个进程,运行它,等待下一个命令的到来。直到关机。
如何证明cpu是多进程执行的?
在这里插入图片描述
打开任务管理器就好啦,同样,任务管理器也是一个进程。

操作系统是怎么支持多进程图像的

1,操作系统是如何组织多进程的?
操作系统感知、组织进程全靠PCB。如何组织呢?在PCB这个结构体之上形成一些数据结构(队列);进程可能有几种状态,有正在执行的进程(运行态),有准备好了只等cpu来执行的进程(就绪态),有还缺少一些东西没准备好在等待的进程(阻塞态)。操作系统可以通过进程对应的PCB来知道进程现在所处的状态。根据进程的状态转化可以形成如下的进程状态图:

在这里插入图片描述

新建态表示进程刚创建出来时所处的状态,终止态表示进程运行完之后所处的状态。
箭头表示操作系统的控制作用,操作系统通过控制进程所处的状态来推进进程的运行;对进程进行管理。

根据PCB、状态形成不同都队列,放在不同的位置

2,操作系统如何交替(切换,非常复杂)?
后面会细讲
包括调度和切换,调度是指从就绪队列中选择哪一个进程进入运行态。切换就是如何保留现场之后进入
新的进程,然后还能回来。
调度是一个很深刻的问题,本课程不会详讲,有很多算法问题;只会讲FIFO:公平,但是没有考虑进程执行
的任务的区别。Priority优先级:给每个任务设置优先级
切换:首先保留上一个进程的执行现场,就是将cpu里面的东西保存在进程对应的PCB里面;转到另外一个进程
将进程PCB里面的东西放到CPU里面去;问题就是这些都要精细的控制,控制每个寄存器

3,多进程如何影响?
多个进程之间会相互影响,为什么会相互影响呢?因为多个进程都是存放在内存上面的,如果进程A在执行的时候操作了进程B所在的内存,那么当进程B运行的时候肯定会出问题呀,因此必须要避免。如何避免呢?对地址进行分离,

这是内存管理的内容,基本思路是给每一个进程都分配一个地址映射表,进程A中操作的地址经过映射表之后会映射到实际的物理地址,因为每一个进程都有一个映射表(映射算法不同),所以不同进程代码中相同的地址映射到的实际地址是不同的,也就是说进程中的地址可以一样,因为实际操作的地址不同呀。比如进程A中的[100]经过地址映射到物理地址是80,进程B经过地址映射表之后映射到的地址是20,这样即使进程A和进程B中都操作了[100]这个地址也无所谓,因为实际操作的地址是不一样的。注意这个不是使用CPL和DPL来解决的,CPL和DPL只是用来区分用户态和核心态的。

4,多进程如何合作?
一个进程如果需要依靠另外一个进程的执行结果不就是合作了吗

关于操作系统是如何支持多进程图像这个问题,相信会随着学习的深入理解会越来越深的 ^ - ^

参考资料

哈工大李志军操作系统

                                </div><div data-report-view="{&quot;mod&quot;:&quot;1585297308_001&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/williamgavin/article/details/82750409&quot;,&quot;extend1&quot;:&quot;pc&quot;,&quot;ab&quot;:&quot;new&quot;}"><div></div></div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
                            </div>
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页