cms 美容网站 模版/seo 优化顾问
以下只是个人的理解和总结,或者某些部分根本就是直接摘抄书本,如有错误之处,还请指正和理解(ps:不要批评菜鸡啊,给菜鸡点自信啊)
一、学习新知识
1、从HelloWorld说起
懂了,这本书是为我写的。
2、万变不离其宗
a、简介
最开始的时候,CPU的核心频率很低,计算速度不高,而且当时没有大量的计算需求,这个时候,内存是完全可以跟得上CPU的速度的,他们直接连接在一个总线(BUS)上,而且输入输出设备基本处理的都是字符,所以每一个I/o设备都通过一个I/o控制器与CUP相连。
后来随着CPU核心频率的提高, 内存跟不上CPU的速度,所以有了系统总线,由于需求又有了协调CPU、内存和图形设备的高速的北桥总线,再然后有了专门处理低速设备的南桥总线。
b、SMP与多核
随着发展CPU频率越来越快,然后就顶到了现在技术的天花板,没有办法再提升单个CPU的核心频率,但是人们又想要获取更快的计算速度和效率,所有就有了双核以及多核CPU。
SMP:对称多处理器,就是通过增加CPU的数量来提高计算速度。
理论上将CPU越多,解决问题的速度越快,但是有些问题是无法被拆分为多个独立的子问题的,也就是说两个子问题互相影响,不可以独立处理。作者举了一个很好的例子:一个女人生孩子需要十个月,但是十个女人生孩子却不可以是一个月。
3、站的稿,望得远
计算机软件体系结构
我的理解就是这玩意是分层的,下层定义接口,然后向上层提供接口,上层使用下层提供的接口,然后实现特定的功能。而操作系统就是硬件与应用软件之间的中间层。
应用程序位于软件系统的最上端,然后它们使用的是操作系统的运行库提供的应用程序编程接口。然后操作系统内核层使用的是硬件层提供的硬件接口。
4、操作系统做什么
答案是提供抽象的接口以及管理硬件资源
a、不要让CPU打盹
在早期,计算资源十分重要,所以要极大程度上的利用CPU资源以避免计算资源的浪费。
但是CPU在同一时间只能运行一个程序,但是如果这个程序正好在进行读写操作,那么CPU就会闲置,就会造成资源的浪费,如何避免资源的浪费,有三种方法:
1、最早的方法:多道程序。也就是如果这个程序不使用CPU了,监控程序就会将CPU资源给另外一个程序,这一方法确实提高了CPU的利用率,但是它有一个坏处,就是它只会僵硬的将CPU分配给程序,但是却不会灵活的选择分配给谁。作者也举了一个例子:如果和使用者交互的程序一直得不到CPU资源,那么你可能就会遇到这样的情况,你点了一下浏览器,然后电脑十分钟后给了你反应,你会不会很沮丧。(沮丧不沮丧我不知道,反正我看到这就笑了)
2、分时系统:就是让每个程序都运行一会,然后让出CUP资源给其他程序,这样的话,一段时间内,每个程序都会运行。后面的缺点我没有理解,准备明天搜一下或者问问老师。
3、 多任务系统:操作系统统一分配CPU资源,应用程序都以进程的方式运行,然后操作系统会根据进程的优先级进行CPU的分配。但是如果一个进程占用CPU超出了一段时间,操作系统直接暂停该进程,然后将CPU资源分配给其他进程(抢占式)。如果规定的运行时间很短,那么CPU在进程之间切换的超级快,就会造成多个进程并行的假象。
问题:QQ音乐也是一个应用程序,所以难道它运行的时候也是断断续续的,哦,还有我们的视频播放也是?
应该就是这样的。
b、设备驱动
操作系统作为硬件的上层,他是对硬件的管理和抽象。我觉得这句话很重要。就比如我们程序员在编写一个应用程序的时候,不需要考虑如何与硬件进行互动,我们直接与操作系统进行交流就可以了,操作系统就是硬件的代言人。而且不管硬件是什么型号,大小,以及其他的什么东西之类的,我们都只要考虑操作系统。而操作系统中的硬件驱动就是做这方面的工作的。
硬盘的介绍:一个硬盘会有很多盘面,一个盘面又会分成两面,每一面又按照同心圆划分为很多的磁道,磁道又被划分为多个扇区,一般情况下一个扇区是就是512字节。使用逻辑扇区号为扇区编码。
然后文件的读取就是向文件系统发送信号,然后文件系统收到信号之后又向磁盘驱动发出一个读取某个地址内容的请求,然后磁盘驱动程序在收到请求之后就会向磁盘发出硬件命令,然后磁盘将数据读取到事先色湖之号的内存地址中,然后进行读取。
5、内存不够怎么办
进程的总体目标是希望每个进程从逻辑上来看都可以独占计算机的资源,操作系统的多任务功能使得CPU可以在多个进程之间很好的共享,并且操作系统的I/O模型也很好的实现了I/O设备的共享和抽象,但是如何分配内存?
在早期的计算机上,程序是直接运行在物理内存上的,也就是说,程序在运行时要访问的都是物理地址。我对这句话的理解假设我们的硬件内存有三个地址1,地址2,地址3,这三个地址都是真实存在在内存之上的,而直接运行在内存的程序就直接通过就直接拿着地址1的名字去访问地址1上的内容,拿着地址2的名字直接取访问地址2的内容....这就是直接访问内存的物理地址。
但是如何将计算机上的有限的物理内存分配给多个程序使用,这是一个问题。
假设内存有128MB的容量,程序A运行需要10MB,程序B运行需要100MB,程序C运行需要20MB。假设要运行程序A、B,那就将内存中的0~10MB分给程序A使用,程序B则被分配11~120MB的地址内存。
上述方法的问题:
1、地址空间不隔离。因为这个就是程序直接访问内存上的物理地址,也就是说程序使用的内存空间不是隔离的(这句话我不是很理解,这句话的意思可能就是和后面的通过CPU的映射访问内存相反的情况吧,也就是直接访问内存)。如果恶意的程序一直向内存中写入数据,这样本地址放不下的情况,就可能会访问到其他程序的地址,然后可能会修改其他程序的内容,造成错误。造成计算机环境不安全。
2、内存使用效率低,在 将整个程序装入内存,假如想要运行其他的程序并且现有内存不够的时候,就需要将现有程序读出,然后将想要运行的程序整体读入,效率低。
3、程序运行的地址不固定。就比如程序A,第一次运行在0~10MB的区域,第二次运行的时候就不一定在跟第一次一样的位置了。但是程序编写的时候,程序数据和指令跳转时的目标地址很多都是固定的,这就会对程序的编写造成困难。
a、关于隔离
地址空间:就像一个巨大的数组,数组的每一个元素都是一个字节,数组的每个位置都有自己的编号,数组的大小通过地址空间的地址长度决定,地址长度越长吗,说明编号越多,就说明地址空间的元素越多,就说明地址空间越大。
地址空间分为了两种:物理地址空间和虚拟地址空间。
物理地址空间就是计算机硬件上真实存在的地址空间,并且每一个物理地址空间的地址编号都是唯一的,一台计算机上只有一个。
虚拟地址空间不是真实存在的,是人们想象出来的,使用虚拟地址空间,然后映射到物理地址空间,就可以达到程序空间隔离的效果。
b、分段
方法一:分段
最开始人们使用的是一种分段的方法,基本思路就是将程序所需要的内存空间大小的虚拟空间映射到某个地址空间。
举个栗子:
程序A需要五个地址空间:1,2,3,4,5(以程序A的视角来看的编号)。然后在运行程序A的时候,通过CPU的映射,将这五个空间分别映射到内存编号为010,011,100,101,110的地址空间上去。当程序A想要访问2空间时,CPU通过映射,让A访问内存上的011空间。结果就是对于程序A来说:我不管操作系统和硬件怎么搞,我就认准访问我的1号(或者其他号)空间,至于你们私底下的操作,我不管,我只管我的家务事。
映射函数由操作系统提供,实际地址的转换由硬件完成。
该方法解决了问题1和问题3。
如何解决问题1:使用分段方法不同程序之间就形成了地址隔离,并且如果程序想要访问的地址超出了它应有的地址,那么硬件就会判断这是一个非法请求,然后狠狠的拒绝这个请求,然后将这个请求报告给操作系统或者监控程序,由他来决定如何处理。
如何解决问题3:就是我之前写到的,A只用考虑对自己的一亩三分地进行读写,其他的党给你办了。???抱歉,跑题了,硬件给你办了。
历史遗留问题:分段方法没有解决问题2----内存使用效率问题。分段对于内存区域的映射还是按照程序为单位,如果内存不足,就会涉及到整个程序的读入读出问题,严重影响效率。
c、分页
根据程序的局部性原理,当一个程序在运行的时候,在某个时间段内,它知识频繁地用到了一小部分数据,也就是说,程序的很多数据其实在一个时间段内都是不会用到的,这样的话,这样的话,明天再写。