操作系统

CPU

cpu是中央处理器,是计算机的核心。 cpu通过和寄存器,高速缓存,以及内存交互来执行程序。

主板分为南桥和北桥,北桥主要是内存总线,通往内存。 而南桥主要是慢速设备的IO总线,包括硬盘,网卡等IO设备。

32位cpu最多寻址4g内存,而64位cpu目前来说没有上限。

程序执行过程

通俗分析:每个进程或者线程发出操作请求后,最后会由CPU来分配时间片处理,处理时将操作数传递给CPU,CPU计算将其写回到“本地变量”中,这个变量通常存在于程序所谓的“栈”中,如果多次对这些本地变量进行操作,为了提升运算效率,它们可能会被Cache到CPU的缓存中。

cpu发出指令,将硬盘上的一段程序读入内存,由于cpu和硬盘的速度差距更大,一般使用中断,DMA等方式来将硬盘数据载入内存。 然后cpu通过寄存器以及指令集执行指令,cpu读取内存上的代码,内存上的方法执行是一个栈调用的过程。

高速缓存 读写缓冲区

为了弥补cpu和内存的速度差,cpu配有多级缓存。

一般有一级缓存和二级缓存,缓存根据局部性原理把经常使用的代码加载如缓存,能比直接访问内存快上几百倍。

同样的,内存和硬盘间的速度差距也很大,需要通过读写缓冲区来进行速度匹配,内存写入磁盘时先写入缓冲区,读数据时从缓冲区读取硬盘准备好的数据。

CPU也可以一次做几件事情,所以它会有一个小的Cache区域,将这些内容暂时Cache住,这样距离处理器越近,操作的延迟就越小,整体效率自然就越快。

一般来讲,一级缓存与CPU的延迟一般在2~3ns之间,二级缓存通常为10~15ns,三级缓存为20~30ns,而内存通常会在50ns以上甚至更高。

缓存是有道理的,就近原则可以达到某种场景下的高效。

内存管理和虚拟内存

内存在程序中一直处于主导地位,它是磁盘存储与CPU之间的一座“缓冲区桥梁”,它与CPU通信的速度是磁盘的千倍以上,它几乎没有IOPS概念,带宽也是几十G每秒。从容量上讲,它拥有比CPU的缓存大出几百倍、几千倍的空间来存储程序和数据。

由于程序的大小越来越大,而计算机想要支持多道程序,当一个程序遇到IO操作时转而去执行另一个程序,这就要求内存中装有多个程序的代码了。

然而程序的内存消耗与日俱增,同时装载多个程序越来越困难,所以人们提出了,只在程序需要使用到的时候再把他装入内存,平时把代码放在硬盘中即可。

分页

由于内存需要装载硬盘中的数据,所以需要约定一个存储单元,操作系统把它叫做页,一个页一般长度是8kb或者16kb。内存从硬盘读取数据时读取的是一个页或多个页。

虚拟内存

由于这些代码持久化在硬盘中,占用了一部分空间,并且需要运行时会加载到内存中,所以这部分的空间一般也成为虚拟内存的空间(大小)。

页表和页面置换算法

为了知道每个程序对应的代码存在硬盘中的位置,操作系统需要维护一个程序到页面的映射表,CPU要内存加载一个页面时,首先要访问页表,来得知页面在硬盘中的位置,然后让内存去该位置把对应的页面调入内存中。

为了提升页面调入的效率,也使用了多种的页面置换算法,比如LRU最近最久未使用,FIFO先进先出,时钟法,多级队列法等。

当然,为了进一步提高效率,还会使用多级页表的方式,不过一般需要硬件维护一个页表映射页面的快速转换结构,以便能迅速地完成页面解析和调度。

中断和缺页中断

计算机提供一系列中断指令与硬件进行交互,操作系统可以使用这些中断去控制硬件,比如使用中断通知CPU硬盘的IO操作已经准备好,键盘通过一次又一次的中断来输入字符。

中断一般适用于快速返回的字符设备,比如鼠标键盘,而硬盘这类耗时IO操作,使用中断后cpu仍然需要等待硬盘把数据装入内存。是非常缓慢的。

于是才会使用DMA来完成IO操作,DMA额外提供一个处理器去处理IO操作,当硬盘数据加载到内存中后再去通知CPU操作已完成。

缺页中断就是因为内存中没有cpu需要访问的页面,必须根据页表到硬盘中获取页面,并根据置换算法进行页面调度。
如果找不到对应页面,则程序执行会报错。

分页和分段

分页是上述所说的,通过内存和硬盘的约定,将调度单元设定为一个页面

分段则不同,分段并不是物理意义上的分段,而是逻辑上把代码使用到的空间划分成多个部分,比如受保护部分,公开部分,核心部分等,这样可以更好地描述每个段的代码信息,为使用者提供便利,为了支持程序员的这种需求,操作系统加入了分段的概念,将代码对应的一段虚拟内存划分为不同的逻辑段。

同时为了根据不同段来以不同方式访问内存,操作系统需要另外维护一个段表,以用于段的映射。

由于分段只是逻辑上的概念,所以底层的内存分页仍然是必不可少的,因此在逻辑段的基础上,物理上又会划分为多个页,一个段中可能包含了多个页面。

因此,完善的虚拟内存管理器需要支持段页表,先映射段,再映射页面。

进程与线程

进程

进程是资源分配的基本单位,操作系统为进程开辟一段内存空间,内存空间从高位向低位,包括函数调用栈,变量以及其他区域。CPU根据这些信息配合寄存器进行函数调用和程序执行。

多进程

由于计算机是分时系统,所以多进程的使用不可避免,操作系统需要进行进程的切换,方法是内存指针指向新位置,保存原来的进程信息,同时刷新寄存器等数据。然后开始执行新的进程.

一般操作系统会使用pcb结构来记录进程的信息和上下文。通过他和cpu配合来完成进程切换。

线程

线程是操作系统调度的基本单位,通常将线程理解为轻量级进程,没有线程以前,一般会使用多进程模型,一个程序往往需要多个进程配合使用,但是多进程之间并没有共享内存,导致进程间通信非常麻烦。

线程与进程非常大的区别是,多个线程是共享一个进程资源的,对于OS的许多资源的分配和管理(例如内存)通常是进程级别的,线程只是OS调度的最小单位,线程相对于进程更加轻量一些,它的上下文信息会更少,它的创建和销毁会更加简单,线程因为某种原因被挂起后不会导致整个进程被挂起,一个进程中又可以分配许多的线程。

比如文本输入工具,一边键入文字一边需要保存数据,如果是单进程执行,则每次输入都触发IO操作,非常费时,如果一个进程负责输入展示一个进程负责输入保存,确实速度很快,但是两个进程没办法共享数据。除非使用额外的通讯手段。

多线程

而多线程就好办了,多线程都是基于进程产生的,线程被创建后只需要分配少量空间支持堆栈操作即可,同时线程还共享进程中的内存,所以一般使用进程分配资源,线程进行调度的方式。

操作系统对线程的支持:
一般情况下操作系统都支持线程,并且可以创建内核级线程,内核可以识别线程并且为其分配空间,进行线程调度。
但是内核级线程实现比较复杂,使用起来也不甚方便。

所以往往开发人员会使用用户级线程,用户级线程比如Java的多线程,通过简单的api实现,当需要操作系统支持时,才使用底层调用api接口进行内核级的系统调用。

但是一般情况下用户级线程是不被内核识别的,也就是说,用户级线程会被内核认为是一个进程,从而执行进程的调度。这样的话就没有意义了。

所以一般情况下用户级线程会映射到对应的内核级线程中,内核为进程创建一定数量的内核级线程以供使用。Java中的线程基本上都是使用这种方式实现的。

线程通信和进程通信

线程通信一般只需要使用共享内存的方式即可实现。

而进程通信则需要额外的通信机制。

1 信号量,一般多进程间的同步使用信号量来完成,系统为临界区添加支持并发量为n的信号量,多进程访问临界区资源时,首先需要执行p操作来减少信号量,如果信号量等于0则操作失败,并且挂起进程,否则成功进入临界区执行。

当进程退出临界区时,执行v操作,将信号量加一,并唤醒挂起的进程进行操作。

2 管程,管程是对信号量的一个包装,避免使用信号量时出错。

3 管道,直接连接两个进程,一个进程写入管道,另一个进程可以读取管道,但是他不支持全双工,并且只能在父子进程间使用,所以局限性比较大

4 消息队列

操作系统维护一个消息队列,进程将消息写入队列中,其他进程轮询消息队列看是否有自己的消息,增加了轮询的开销,但是提高了消息的可靠性和易用性,同时支持了订阅消息。

5 socket

socket一般用于不同主机上的进程通信,双方通过ip和port的方式寻址到对方主机并找到监听该端口的进程,为了完成通信,他们先建立tcp连接,在此基础上交换数据,也就完成了进程间的通信。

进程调度

进程调度算法有几种,FIFO先来先服务,短作业优先,时间片轮转,优先级调度,多级反馈队列等。 基本上可以通过名字知道算法的大概实现。

死锁

请参考博文:https://blog.youkuaiyun.com/qq_28602957/article/details/53508447

死锁的必要条件:

1、互斥条件:资源必须是互斥的,只能给一个进程使用

2、占有和等待条件:占有资源时可以请求其他资源

3、不可剥夺条件:资源占有时不会被抢

4、环路等待条件:有两个以上的进程组成一个环路,每个进程都在等待下一个进程的资源释放。

死锁的处理方法:

(一)破坏互斥条件

例如假脱机打印机技术允许若干个进程同时输出,唯一真正请求物理打印机的进程是打印机守护进程。

这样子就破坏了互斥条件,转而使用单个队列串行执行操作。

(二)破坏占有和等待条件

一种实现方式是规定所有进程在开始执行前请求所需要的全部资源。

分配了全部资源就不需要去等待其他资源。

(三)破坏不可抢占条件

允许抢占式调度。

(四)破坏环路等待

给资源统一编号,进程只能按编号顺序来请求资源。

按正确顺序请求资源,就不会发生死锁。

死锁避免

银行家算法用于在程序运行时避免发生死锁。

银行家算法用于在程序运行时判断资源的分配情况是否是安全状态,如果某一步骤使程序可能发生死锁,银行家算法会拒绝该操作执行,从而避免进入不安全状态。(细节略)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值