《现代操作系统》– 死锁、银行家算法

1.资源:进程对设备、文件等获得独占性的访问权时有可能会发生死锁,为了尽可能地通用化,我们将这种需排它使用的对象称为资源。资源可以是硬件设备(如磁带机),或一组信息(如数据库中一个加锁的记录)。计算机中通常有多种资源。有些类型的资源有多个相同的实例,如三台磁带机。当某一资源有若干拷贝时,其中任一个均可用来满足对资源的请求。简言之,资源是在任何时刻只能被单个进程使用的任何对象。

 

2.资源又分为可抢占资源和不可抢占资源。

可抢占资源:可从拥有它的进程处剥夺而没有任何副作用,存储器是一类可剥夺资源。

不可抢占资源:无法在不导致相关计算失败的情况下将其从属主进程处剥夺。若一个进程已开始打印,那么剥夺其占用的打印机并分配给另一进程将使打印结果一片混乱。打印机是不可剥夺的。

使用一个资源的事件顺序是:
(1)申请资源
(2)使用资源
(3)释放资源

 

3.死锁的定义:如果一个进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件,那么,该进程集合就是死锁的。

 

4.死锁的四个必要条件

:互斥条件。每个资源要么已经分配给了一个进程,要么就是可用的,不能同时被两个或两个以上的进程占有。

:占有和等待条件。已经得到了某个资源的进程可以再请求新的资源。

:不可抢占条件。已经分配给了一个进程的资源不能强制性的被占用,它只能被占有它的进程显式地释放。

:环路等待条件。死锁发生时,系统中一定有由两个或两个以上的进程组成的一条环路,该环路中的每个进程都在等待下一个进程所占用的资源。

死锁发生时,以上四个条件一定是同时满足。如果其中任何一个条件不成立,死锁就不会发生。

 

5.死锁如何产生以及如何避免的例子:

 

 

 

总而言之,有四种处理死锁的策略:

:忽略该问题。也许如果你忽略它,它也会忽略你。

:检测死锁并恢复。让死锁发生,检测他们是否发生,一旦发生死锁,采取行动解决问题。

:仔细对资源进行分配,动态地避免死锁。

:通过破坏引起死锁的四个必要条件之一,防止死锁的产生。

 

6.检测死锁的算法:

:对图中的每一个节点N,将N作为起始点执行下面5个步骤。

:将L初始化为空表,并清除所有的有向边标记。

:将当前节点添加到L的尾部,并检测该节点是否在L中已出现过两次。如果是,那么该图包含了一个环(已经在L),算法结束。

:从给定的节点开始,检测是否存在没有标记的从该节点的弧(有向边)。如果存在的话,做第5步,如果不存在,跳到第6步。

:随机选取一条没有标记的从该节点出发的弧(有向边),标记它。然后顺着这条弧线找到新的当前节点,返回第3步。

:如果这一节点是起始节点,那么表明该图不存在任何环,算法结束。否则意味着我们走进了死胡同,所以需要移走该节点,返回到前一个节点,即当前节点前面的一个节点,并将它作为新的当前节点,同时转到第3步。

其实这一算法就是一次将每一个节点作为一棵树的根节点,并进行深度优先搜索。

 

 

 

 

7.每种类型多个资源的死锁检测

死锁检测算法如下:

:寻找一个没有标记的进程Pi,对于它而言R矩阵的第i行向量小于或等于A

:如果找到了这样一个进程,那么将C矩阵的第i行向量加到A中,标记该进程,并转到第1步。

:如果没有这样的进程,那么算法终止。

算法结束时,所有没有标记过的进程(如果存在的话)都是死锁进程。

 

 

 

进程3被满足,然后进程2,进程1,所以上图不存在死锁。

 

8.从死锁中恢复

利用抢占恢复:在不通知原进程的情况下,将某一资源从一个进程强行取走给另一个进程使用,接着又送回。

利用回滚恢复:将进程复位到一个更早的状态,那时它还没有取得所需资源,接着就把这个资源分配给一个死锁进程。

通过杀死进程恢复:杀死环中的一个进程,如果走运的话,其他进程将可以继续。如果这样行不通的话,就需要继续杀死别的进程直到打破死循环。

 

9.死锁避免

 

 

 

资源轨迹图

安全和不安全状态

进程序列{P1,P2, ……Pn}Ti时刻是安全的序列,当且仅当存在

Pi申请的附加资源数≤Pi已保持的资源数+当前系统可用的资源数

 

10.银行家算法:就是对每一个请求进行检查,检查如果满足这一请求是否会达到安全状态。若是,那么就满足该请求;若否,那么就推迟对这一请求的满足。为了看状态是否安全,银行家看他是否有足够的资源满足某一客。如果可以,那么这笔投资认为是 能够收回的,并且接着检查最接近最大限额的一个客户,以此类推。如果所有投资最终都被收回,那么该状态是安全的,最初的请求可以批准。

 

 

 

a.安全 b.安全 c.不安全

多个资源的银行家算法:

下边的三个向量分别表示总的资源E、已分配资源P,和剩余资源A。由E可知系统中共有6台磁带机,3台绘图仪,4台汀印机和2CD-ROM。由P可知当前已分配 了5台磁盘机,3台绘图仪,2台打印机和2CDROM。该向量可通过将左边短阵的各列 相加得到,剩余资源向量可通过从资源总数中减去已分配资源数得到。

 

 

 

检查一个状态是否安全的步骤如下:

(1)查找右边矩阵中是否有一行,其未被满足的设备数均小于或等于向量A。如果找不到,则系统将死锁,因为任何进程都无法运行结束。

(2)若找到这样一行,则可以假设它获得所需的资源并运行结束,将该进程标记为结束,并将资源加到向量A上。

(3)重复以上两步,直到所有的进程都标记为结束。若达到所有进程结束。则状态是安
全的,否则将发生死锁。

 

11.死锁预防:

破坏互斥条件:如果资源不被一个进程所独占,那么死锁肯定不会产生。当然,允许两个进程同时使用打印机会造成混乱,通过采用假脱机打印机技术允许若干个进程同时产生输出。

破坏占有和等待条件:规定所有进程在开始执行前请求所需的全部资源,如果所需的全部资源可用,那么就将他们分配给这个进程,于是该进程肯定能运行结束。如果有一个或多个资源正被使用,那么就不进行分配,进程等待。

破坏不可抢占条件:即允许进程强行从占有者那里夺取某些资源。就是说,当一个进程已占有了某些资源,它又申请新的资源,但不能立即被满足时,它必须释放所占有的全部资源,以后再重新申请。它所释放的资源可以分配给其它进程。这就相当于该进程占有的资源被隐蔽地强占了。

破坏环路等待条件:一种是保证每个进程在任何时刻只能占用一个资源,如果要请求另外一个资源,它必须先释放第一个资源。第二种是将所有资源统一编号,所有请求必须按资源编号提出。

 

12.饥饿:和死锁非常相近的一个问题是饥饿(starvation)。在动态运行的系统中,在任何时刻都会产生申请资源。这就需要规定一些策略来决定在什么时候,谁获得什么资源。虽然这个策略表面上很有道理,但依然有叫能使一些进程永远得不到服务,虽然它们并没有被死锁。

在一个繁忙的系统中,有一个进程有一个很大的文件要打印,每当打印机空闲,系统纵观所有进程,并把打印机分配给打印最小文件的进程。如果存在一个固定的进程流,其中的进程都是只打印小文件,那么,要打印大文件的进程永远也得不到打印机。很简单,它会如饥饿而死一般(无限制地推后,尽管它没有被阻塞)。

饥饿可以通过先来先服务资源分配策略来避免。

《现代操作系统》输入/输出、磁盘调度算法

1.I/O设备的概念

存储设备:用来存放各种信息的设备成为存储设备,例如:软盘、硬盘、光盘和磁带等。

I/O设备:用来向计算机输入和输出信息的设备,例如:键盘、鼠标、显示器、打印机等。

在现代计算机系统中有些设备既可以做存储设备,也可以做I/O设备,例如:软盘、硬盘等。

计算机外部设备组成:

 

 

 

2.设备控制器

操作系统与控制器打交道,而不是与设备直接打交道。

控制器的任务是把串行的位流转换为字节块,并进行必要的错误校正工作。字节块通常首先在控制器内部的一个缓冲区按位进行组装,然后在对校验和进行校验并证明字节块没有错误后,再将它复制到主存中。

 

3.设备I/O方式

①询问(Query):实时系统中必需采用,在一般简单系统中也广泛采用,但系统开销较大,每次进行输入输出工作,都需要由主机CPU干预;

②中断(interrupt):当主机接到外部信号(如内、外部设备完成或出错)时,马上停止原来的工作,考虑去处理这一事件,处理完毕后,主机又回到原来的断点继续工作。

有硬中断和软中断之分,中断按级别分类排队工作;可按字符、字、块的传递产生中断;实时控制常用实时时钟中断,起自动控制作用;中断工作主要由中断请求、中断响应和中断服务处理组成。“中断”的产生使管理工作更能“自动化”.

③通道(Channel):有硬通道和软通道之分,硬通道,例如,典型的DMA(Direct Memory Access)工作方式;软通道是软件设计中使用的各种“标识”、“缓冲”等;

医生(CPU)查房(“询问”),以便及时掌握病情(I/O请求)。病床旁红灯是(I/O)紧急请求医生(CPU)按钮(“中断请求”)。常规医疗处理医生(CPU)委托护士(“硬通道”)去做。但护士(通道)只有执行权而无修改权。

 

4.数据传送控制方式

①程序直接控制方式:程序直接控制方式是指由程序直接控制内存或CPU和外围设备之间进行信息传送的方式。通常又称为“忙—等”方式或循环测试方式。

在数据传送过程中,必不可少的一个硬件设备是I/O控制器,它是操作系统软件和硬件设备之间的接口,它接收CPU的命令,并控制I/O设备进行实际的操作。

下面讲述程序直接控制方式的工作过程。由于数据传送过程中输入和输出的情况比较类似,下面只给出输出数据时的工作过程。

1)把一个启动位为“1”的控制字写入该设备的控制状态寄存器。

2)将需输出数据送到数据缓冲寄存器。

3)测试控制状态寄存中的“完成位”,若为0,转(2),否则转(4)。

4)输出设备将数据缓冲寄存器中的数据取走进行实际的输出。

②中断控制方式:

1)进程需要数据时,将允许启动和允许中断的控制字写入设备控制状态寄存器中,启动该设备进行输入操作。

2)该进程放弃处理机,等待输入的完成。操作系统进程调度程序调度其他就绪进程占用处理机。

3)当输入完成时,输入设备通过中断请求线向CPU发出中断请求信号。CPU在接收到中断信号之后,转向中断处理程序。

4)中断处理程序首先保护现场,然后把输入缓冲寄存器中的数据传送到某一特定单元中去,同时将等待输入完成的那个进程唤醒,进入就绪状态,最后恢复现场,并返回到被中断的进程继续执行。

5)在以后的某一时刻,操作系统进程调度程序选中提出的请求并得到获取数据的进程,该进程从约定的内存特定单元中取出数据继续工作。

③DMA方式:DMA方式又称直接存储器访问(Direct Memory Access)方式。其基本思想是在外设和主存之间开辟直接的数据交换通路。

DMA方式的特点是:

1)数据传送的基本单位是数据块。

2)所传送的数据是从设备送内存,或者相反。

3)仅在传送一个或多个数据块的开始和结束时,才需中断CPU,请求干预,整块数据的传送是在DMA控制器控制下完成的。

DMA控制器一次给打印机提供一个字符,而不必打扰CPU,本质上,DMA是程序控制I/O,只是由DMA控制器而不是主CPU做全部工作。

④通道控制方式:通道控制方式与DMA方式相类似,也是一种内存和设备直接进行数据交换的方式。与DMA方式不同的是,在通道控制方式中,数据传送方向存放数据的内存始址及传送的数据块长度均由一个专门负责输入/输出的硬件——通道来控制。另外,DMA方式每台设备至少需要一个DMA控制器,而通道控制方式中,一个通道可控制多台设备与内存进行数据交换。

 

5.缓冲技术

引入缓冲的主要目的有以下几点:

1.缓和处理机和I/O设备间速度不匹配的矛盾

2.减少对CPU的中断次数

3.提高CPU和I/O设备之间的并行性

①单缓冲:单缓冲是操作系统提供的最简单的一种缓冲形式。每当一个进程发出一个I/O请求时,操作系统便在主存中为之分配一缓冲区,该缓冲区用来临时存放输入/输出数据。

②双缓冲:解决外设之间并行工作的最简单的办法是设置双缓冲。当一个缓冲区正在被复制到用户空间的时候,另一个缓冲区正在收集新的输入。

双缓冲方式和单缓冲方式相比,虽然双缓冲方式能进一步提高CPU和外设的并行程度,并能使输入设备和输出设备并行工作,但是在实际系统中很少采用这一方式,这是因为在计算机系统中的外设很多,又有大量的输入和输出,同时双缓冲很难匹配设备和CPU的处理速度。因此现代计算机系统中一般使用环形缓冲或缓冲池结构。

③环形缓冲:环形缓冲技术是在主存中分配一组大小相等的存储区作为缓冲区,并将这些缓冲区链接起来,每个缓冲区中有一个指向下一个缓冲的指针,最后一个缓冲区的指针指向第一个缓冲区,这样n个缓冲区就成了一个环形。此外,系统中有个缓冲区链首指针指向第一个缓冲区。

 

 

 

④缓冲池:缓冲池中的缓冲区一般有以下三种类型:空闲缓冲区、装输入数据的缓冲区和装输出数据的缓冲区。

空缓冲队列emq。输入队列inq。输出队列outq。

 

 

 

6.假脱机:是多道程序设计系统中处理独占I/O设备的一种方式。考虑一种典型的假脱机设备:打印机。尽管在技术上可以十分容易地让任何用户进程打开表示该打印机的字符特殊文件,但是假如一个进程打开它,然后很长时间不使用,则其他进程都无法打印。

另一种方法是创建一个特殊进程,称为守护进程,以及一个特殊目录,称为假脱机目录。一个进程要打印一个文件时,首先生成要打印的整个文件,并且将其放在假脱机目录下。由守护进程打印该目录下的文件,该进程是允许使用打印特殊文件的惟一进程。通过保护特殊文件来防止用户直接使用,可以解决某些进程不必要长期空占打印机的问题。

 

7.磁盘:

控制器是否可以同时控制两个或多个驱动器进行寻道,这就是重叠寻道。

在老式的磁盘上,每磁道扇区数对所有柱面都是相同的。而现代磁盘则被划分成环带,外层的环带比内层的环带拥有更多的扇区。

光盘:聚碳酸酯基片中的凹陷处成为凹痕(0),凹痕之间未被烧的区域称为槽脊(1)。

 

8.磁盘调度算法:

决定因素:①寻道时间(将磁盘臂移动到适当的柱面上所需的时间)②旋转延迟(等待适当扇区旋转到磁头下所需的时间)③实际数据传输时间

①先来先服务:很难优化寻道时间。

11,1,36,16,34,9,12                      111

②最短寻道优先(SSF):处理与磁头距离最近的请求以使寻道时间最小化。

 

 

 

 

11,12,9,16,1,34,36                      61

③电梯算法:当一个请求处理完之后,磁盘或电梯的驱动程序检查方向位,如果是UP,磁盘臂或电梯舱移至下一个更高的未完成的请求。如果更高的位置没有未完成的请求,则方向取反。

 

 

 

11,12,16,34,36,9,1                      60

 

9.时钟软件

在不同的操作系统中,时钟驱动程序的任务也不同,但一般包括以下内容:

(1)维护日期时间。
(2)防止进程的运行时间超出其允许的时间。
(3)对CPU使用进行记帐。
(4)处理用户进程提出的时间闹钟系统调用。
(5)对系统某些部分提供监视定时器。
(6)支持直方图监视和统计信息搜集。

第一项功能维护日期时间(也称为实际时间)并不困难。它仅需要像我们前面提到的那样,每次时钟滴答增加一次计数器。需要注意的是日期时间的位数。对于60Hz的时钟,32位的计数器刚刚超过两年就会溢出。显然系统无法用32位存储1970年1月1日开始的滴答数来存储实际时间。

有三种方法解决这个问题,第一种方法是使用64位计数器。因为1秒以内需执行多次维护计数器的工作,因此提高了维护时钟的代价。

第二种办法使用一个辅助计数器来对滴答计数直至累计一秒为止。因为232秒超过136年,这种方法直至22世纪都会工作得很好。

第三种方法按滴答计数,但是相对系统启动时间,而不是相对一个确定的外部时刻。当读后备时钟或用户输入实际时间时,根据当前的时间计算系统启动时间并以一种方便的格式存储于系统中。以后当询问每天的时间时,存储的时间加上计数器中的时间就是当前时间。

 

 

 

时钟的第二项功能是防止进程运行太长的时间。无论何时启动一个进程,调度程序都应该用一个以时钟滴答计算的进程时间片的值初始化一个计数器。当每次时钟中断时,中断驱动程序把时间片计数器减1,当它为零时,时钟驱动程序调用调度程序来建立其他的进程。

第三项功能为CPU记帐。完成这项工作的最方便的方法是无论何时启动一个进程就启动一个和主系统定时器不同的第二个定时器,当进程暂停时,读出该定时器的内容看一看进程运行了多长时间。为了使记帐正确,当中断发生时,保存第二个定时器的内容,当中断结束时,恢复第二个定时器的内容。

 

《现代操作系统》文件系统

1.文件的定义:文件是具有标识符(文件名)的一组相关信息的集合。标识符是用来标识文件的。不同的系统对标识符的规定有所不同。文件的确切定义有两种说法:

1)文件是具有标识符的相关字符流的集合。(2)文件是具有标识符的相关记录的集合。

 

2.UNIX系统中的文件名:文件名是一个不大于14个字符的字符串。并且区分英文字母的大小写。在UNIX系统中文件名就是一个字符串,没有文件名和文件扩展名之分,文件的类型由用户命名时确定。

例如,li.cUNIX系统认为这个文件名的长度是4个字符。而在DOSWINDOWS系统中则解释这个文件名,li是文件名,c是文件扩展名,表示该文件是一个C语言的源程序文件,而.是文件名和文件扩展名的分隔符。

 

3.文件系统的定义:文件系统是操作系统中负责存取和管理文件信息的机构。它由管理文件所需的数据结构(如文件控制块,存储分配表等)和相应的管理软件以及访问文件的一组操作组成。

从系统的角度看:文件系统是一个负责文件存储空间管理的机构。

从用户的角度看:文件系统是用户在计算机上存储信息、和使用信息的接口。

 

4.文件结构:

 

 

 

a 字节序列:操作系统把文件看成字节序列提供了很大的灵活性。用户程序可以在文件中加入任何内容,并且以任何方便的形式来命名。这时,处理文件结构的任务由用户完成,操作系统无法提供任何帮助,但也不会设置障碍。

b 记录序列:在这个模型中,文件是一个固定长度记录的序列,每条记录都有内部结构。

树:这种方式中,文件由一棵记录树构成,并非每条记录都具有同样的长度。在记录的固定位置包含一个关键字域。记录树按关键字域进行排序,这便于对特定关键字进行快速查找。

 

5.文件存取:早期操作系统只有一种文件存取方式:顺序存取。进程在这些系统中可以从头顺序读取文件的全部字节或记录,但不能跳过某一些内容,也不能不按顺序读取。顺序读取文件是可以返回到起点的,需要时可多次读取该文件。在存储介质是磁带而不是磁盘时,顺序存取文件是很方便的。当用磁盘来存储文件时,我们可以不按顺序地读取文件中的字节或记录,或者按照关键字而不是位置来存取记录。这种能够以任何次序读取其中字节或记录的文件称作随机读取文件。许多应用程序需要这种类型的文件。如数据库系统。

 

6.文件属性:反映文件的类型、存取控制、等。常见属性有:文件类型、文件长度、文件的位置、文件的存取控制和文件的建立时间等。其它属性见下表

 

 

 

7.目录

文件控制块(也称目录项):每个文件有唯一的一个文件控制块也称目录项。包括文件名、文件类型、位置、大小、存取保护信息、使用计数、时间信息。对文件的操作须先找到它才能进行其它操作。
文件目录:控制块的有序集合称文件目录(完全由目录项构成的文件称目录文件)

文件目录结构:

一级目录系统:目录系统最简单形式是在一个目录中包含所有的文件。这有时称为根目录,但是由于只有一个目录,所以其名称并不重要。

层次目录系统:它将目录和文件放在一起,将目录也做成文件,形成树形多层次的目录结构:所有目录项统一增加一项指明是目录还是文件,并规定一没有上层的目录项为根目录,构成一树状逻辑结构。

UNIX操作系统中的文件卷是文件、层次结构目录和i节点(i-node)的三者组合体,它由全路径可确定唯一文件。硬盘可以在逻辑上划分成多个文件系统的文件卷,利用命令/etc/mount,/etc/umount可方便地动态装卸。

 

 

 

cp ../lib/dictionary .                拷贝上一级下lib/dicationary到当前目录。

 

8.文件系统的实现

顺序文件:将一个文件中逻辑上连续的信息存放到若干连续的物理块中,这类文件叫连续文件,又称顺序文件。

优点:简单,支持顺序读取和随机存取,顺序存取速度快,所需的磁盘寻道次数和寻道时间最少。

 

 

 

串联文件:一个文件的信息存放在若干不连续的物理块中,各块之间通过指针连接,前一个物理块指向下一个物理块。

优点:提高了磁盘空间利用率,不存在外部碎片问题,有利于文件插入和删除,有利于文件动态扩充。

 

 

 

使用文件分配表:使用文件分配表,可以根据其实块,然后在文件分配表中查找该块的下一个磁盘块,一直到结束标志。

④i节点其实就是可以这么认为,把i节点看作是一个指向磁盘上该文件存储区的地址。只不过这个地址我们一般是没办法直接使用的,而是通过文件名来间接使用的。事实上,i节点不仅包含了文件数据存储区的地址,还包含了很多信息,比如数据大小,等等文件信息。但是i节点是不保存文件名的。文件名是保存在一个目录项中。每一个目录项中都包含了文件名和i节点。

 

9.文件目录

MS-DOS中的目录:

图示是一个MS—DOS的目录项。它总共32个字节长,其中包含了文件名、文件属性和第一个磁盘块的块号。根据第一个磁盘块的块号,根据链表得到文件所在块。

 

 

 

MS-DOS中,目录可以包含其他日录,从而形成层次文件系统。通常在MS-DOS中,每个应用程序在根目录下创建一个目录,把它的所有文件都放在这个目录下,因此不同 的应用程序不会发生冲突。

UNlX中的目录:

UNIX中使用的目录结构非常简单,如图示,每个目录项只包含一个文件名及 其i-节点号。有关文件类型、长度、时间、拥有者和磁盘块等所有信息都放在i-节点中。有些UNIX系统有不同的布局,但无论如何,目录项中最终要包含一个ASCII字符串和一 个i-节点号。

 

 

 

在打开文件时,文件系统必须根据给出的文件名找到它所在的磁盘块。让我们分析如何来查找路径名/user/ast/mbox。尽管是以UNIx作为例子,但是这个查找算法对所有的层次目录系统基本上都一样。首先文件系统找到根目录。在UNIx中,根目录的i-节点位于磁盘上的固定位置。

然后在根目录中查找路径的第一部分,usr,从而也就获得了文件/usri-节点号。因为每个i-节点都位于磁盘的固定位置,所以根据i-节点号找到i-节点是很直接的。利用这个i-节点,文件系统找到目录/usr,并接着查找下一部分ast。当找到ast目录项后,得到目录/usrasti-节点。从而找到目录/usrast并在该目录中查找文件mbox。接着,文件mboxi-节点被读入内存,并保存在内存中,直至关闭该文件。

 

 

 

相对路径名的查找也类似。只是,相对路径名从工作目录,而不是根目录开始查找。每个目录在创建时都含有“.”“..”项。“.”项给出当前 目录的i-节点号,“..”项给出了其父目录的i-节点号。因而,查找..dickprog.c的过程仅仅是在工作目录中查找“..”项,找到父目录的i-节点号,并在父目录中查找到dick目录。我们不需要特别的机制来处理这些文件名,就目录系统而言,和其他的文件名一样,他们都仅仅是一些ASCII字符。

 

10.文件系统性能

减少磁盘访问次数最常用技术是块高速缓存(block cache或者buffer cache)。在这里,高速缓存是一些块,他们逻辑上属于磁盘,但基于性能的考虑而保存在内存中。

在管理高速缓存时,用到了不同的算法。一个常用算法是:检查所有的读请求,看看所需的块是否在高速缓存中。如果在,无须访问磁盘便可进行读操作。如果块不在高速缓存中,首先要把它读到高速缓存,再拷贝到所需的地方。之后,对该块的读写请求都通过高速缓存完成。

块提前读

在需要用到块之前,试图提前将其写入高速缓存,从而提高命中率。

减少磁盘臂运动

把有可能顺序存取的块放在一起,当然最好是在同一个柱面,从而减少磁盘臂的移动次数。

《现代操作系统》存储管理、虚拟地址转换、淘汰换页算法

1.有两种处理内存超载的通用方法。最简单的策略是交换技术,即把一个进程完整调入内存,使该进程运行一段时间,然后把它存回磁盘。空闲进程主要存储在磁盘上,所以当他们不运行时就不会占用内存(尽管他们的一些进程会周期性地被唤醒以完成相关工作,然后又进入睡眠状态)。另一种策略是虚拟内存,该策略甚至能使程序在只有一部分被调入内存的情况下运行。

 

2.地址重定位:把程序地址空间的逻辑地址转换为存储空间的物理地址的工作叫地址重定位。又叫地址映射,或地址变换。

地址重定位的原因:
地址空间的逻辑地址往往与分配到的存储空间的物理地址不一致,
而处理机执行用户程序时,所要访问的指令和数据地址必须是实际的物理地址。

 

2.空闲内存管理:一般而言,有两种方式跟踪内存使用情况:位图和空闲链表。

①:使用位图的存储管理:使用位图方法时,内存可能被划分成小到几个字或大到几千字节的分配单元。每个分配单元对应于位图中的一位,0表示空闲,1表示占用(或者相反)。

 

 

 

②:使用链表的存储管理:维护一个记录已分配内存段和空闲内存段的链表。链表中的每一个结点都包含以下域:空闲区(H)或进程(P)的指示标志、起始地址、长度和指向下一结点的指针。

 

3.常用的空闲区链的管理的三种分配算法:

首次适应(first fit)法:要求空闲区按地址递增的次序排列。当进行内存分配时,从起始地址最小的空闲区开始扫描,直到找到一个能满足其大小要求的空闲区为止。分一块给请求者,余下部分仍留在空闲链中。

特点:优先利用低地址部分的空闲区,保留了高地址部分的大空闲区。
低地址端可能留下许多很少的空闲区,而每次查找是从低地址部分开始,会增加查找开销。

下次匹配法(next-fit):按分区的先后次序,从上次分配的分区起查找(到最后分区时再回到开头),找到符合要求的第一个分区。
特点:该算法的分配和释放的时间性能较好,使空闲分区分布得更均匀,但较大的空闲分区不易保留。

最佳适应(best fit)法:存储分配程序要扫描所有空闲区,以获得能满足进程需求且为最小的空闲区。
特点:因为分配分区要查找整个链表,所以比首次适应算法效率低。因为它可能把主存划分得更小,成为无用的碎片,所以它比首次适应要浪费更多的空贮空间。

最坏适应(worst fit)法:分配存储空间时,要扫描整个空闲区表,直到找到能满足进程要求且为最大的空闲区为止。然后,一分为二,一部分给进程,另一部分仍留在表中。
缺点:由于最大的空闲区总是首先被分配而进行划分,当有大作业到来时,其存储空间的申请往往得不到满足。

 

4.虚拟内存的基本思想:每个程序拥有自己的地址空间,这个空间被分隔成多个块,每一块称作一页或页面。每一页有连续的地址范围。这些页被映射到屋里内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时,由硬件立即执行必要的映射。当程序引用到一部分不在物理内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的指令。

 

5.分页:我们程序产生的如:MOV REG,1000这些地址称为虚拟地址,它们构成了一个虚拟地址空间。在没有虚拟内存的计算机上,系统直接将虚拟地址送到内存总线上,读写操作使用具有同样地址的物理内存字;而在使用虚拟内存的情况下,虚拟地址不是被直接送到内存总线上,而是被送到内存管理单元,MMU把虚拟地址映射为物理内存地址。

 

 

 

图一

 

 

 

图二

当程序试图访问地址0时,比如使用这条指令:

MOV   REG,0

虚地址0将被送往MMU。MMU看到虚地址落在页0范围内(0到4095),根据它的映射这个页对应的是页框2(8192到12287),因此MMU把地址变换为8192并把地址8192送到总线上。内存板对MMU一无所知,它只看到一个对地址8192读或写的请求并且执行它。MMU从而有效地把所有从0到4095的虚地址映射到了8192到12287的物理地址。

如果MMU注意到这个页没有映射,于是使CPU陷入操作系统,这个陷入称为缺页。操作系统找到一个很少使用的页框并把它的内容写入磁盘,随后把需引用的页取到刚才释放的页框中,修改映射;然后重新启动引起陷入的指令。

 

6.MMU的内部结构以了解它是怎么工作的,以及为什么我们选用的页面大小是2的次幂。在图中我们可以看到一个虚地址的例子,虚地址8196(二进制是0010000000000100)用图示的MMU的映射进行映射,输入的16位虚地址被分为4位的页号和12位的偏移量,4位的页号可以表示16个页面,12位的位移可以为一页内的全部4096个字节编址。

 

 

 

页号可用作页表的索引,以得出对应于这个虚页的页框号。如果在/不在(Prsent/absent)位是0,则将引发一个操作系统的陷入;如果这个位是1,在页表中查到的页框号将被复制到输出奇存器的高三位中,加上输入虚地址中的12位偏移,就构成了15位的物理地址。输出 寄存器的内容随即被作为物理地址送到内存总线。

 

7.虚拟地址到物理地址的映射可以概括如下:

虚地址被分成虚页号(高位)和偏移(低位)两部分,虚页号被用做页表的索引以找到该虚页对应的页表项,从页表项中可以找到页框号(如果有的话)。随后页框号被拼接到偏移的高位端,形成送往内存的物理地址。页表的目的是把虚页映射为页框。从数学角度而言,页表是一个函数,它的参数是虚页号,结果是物理页框号。通过这个函数可以把虚地址中的虚页域替换成页框域,从而形成物理地址。

 

8.表项:表项的结构是与机器密切相关的,但不同机器的表项存储的信息大致相似。在图3-14中我们给出了页表项的样本,不同计算机页表项的大小不一样,但32位是一个一般的尺寸。最重要的域是页框号,毕竟页映射的目的是找到这个值;其次是在/不在位,这一位是1时这个表项是有效的可以被使用,如果是0,表示这个表项对应的虚页现在不在内存中,访问这一位为0的页会引起一个页面故障(缺页)。

 

 

 

 

9.多级页表:为了避免把庞大的页表始终保存在内存中,许多计算机使用了多级页表

 

 

 

32位的虚地址划分为10位(210)的PT1域、10位(210)的PT2域和12位(212)的偏移。因为偏移是12位,所以页长是(212=)4K,页面共有220个。

举一个例子,虚地址0×00403004(十进制4,206,596)位于数据部分(222-4206596=)12,292字节处。它对应的PT1=1、PT2=3、偏移(12292-3*212)=4。MMU首先用PT1作为索引访问顶级页表得到表项1,它对应的地址范围是4M到8M;随后它用PT2作为索引访问刚刚找到的二级页表并得到表项3,它对应的地址范围是在它的4M块内的12288到16383(即绝对地址4,206,592到4,210,687)。这个表项含有虚地址0×00403004所在页的页框号。如果这个页不在内存中,在/不在位将是0,一个页面故障将被引发;如果这个页在内存中,从二级页表中得到的页框号将和偏移(4)结合构成物理地址并通过总线送到存储器。

 

10.请求淘汰换页算法:

①:最优页面置换算法:置换将来使用次数少的页面。

②:最近未使用页面置换算法:利用在页表中设置一个访问位即可实现,当某页被访问时,访问位置“1”,否则访问位置“0”当需要淘汰一页时,从那些访问位为“0”的页中选一页进行淘汰。系统周期性地对所有访问位清零。

③:先进先出页面置换算法: 先进入内存的页面先淘汰。实现是在页表中登记进入的次序,并将各个已分配的页面按分配时间顺序连接起来,组成FIFO队列。优点是实现简单,缺点是遇到常用的页效率低下,并可能产生Belady现象(所谓Belady现象是指分配的页面数增多,缺页次数反而增加的现象)。

④:第二次机会页面置换算法:为了避免FIFO可能会把经常使用的页替换出去的问题,我们可以对它做一个简单的修改,对最老页面的R位进行检查。如果R位是0,那么这个页既老又没用,应该被立刻替换掉;如果是1,就清除这个位,把这个页放到页链表的尾端,修改它的装入时间让它就保刚装入的一样,然后继续搜索。

⑤:时钟页面置换算法:

尽管第二次机会算法是一个较合理的算法,但它经常要在链表中移动页面。既降低了效率,又是不必要的。一个更好的办法是把所有的页面保存在一个类似钟表面的环形链表中,如图示,有一个表针指向最老的页面。

  在发生页面故障时,算法首先检查表针指向的页面,如果它的R位是0就淘汰掉这个页,并把新页插入这个位置,然后把表针前移一个位置;如果R位是1就清除R位并把表针前移一个位置,重复这个过程直到找到一个R位为0的页为止。了解了这个算法的工作方式我们就不奇怪为什么它被叫做时钟了,它和第二次机会算法的区别仅仅是实现不同。

 

 

 

 

⑥:最近最少使用页面置换算法:当要淘汰某页时,选择离当时时间最近的一段时间内最久没有使用过的页面先淘汰。该算法的出发点是,如果某页被访问了,则可能它马上还要被访问,或者反过来说,如果某页面很长时间未被访问,则它在最近一段时间也不会被访问。LRU的实现是一件十分困难的事情,我们一般采用它的近似算法。

 

11.FIFO算法和LRU算法:

 

 

 

12.缺页中断处理

缺页中断处理发生的时间顺序:

①:硬件陷入内核,在堆栈中保存程序计数器。大多数机器将当前指令的各种状态信息保存在特殊的CPU寄存器中。

②:启动一个汇编代码例程保存通用寄存器和其他易失的信息,以免被操作系统破坏。这个例程将操作系统作为一个函数来调用。

③:当操作系统发现一个缺页中断时,尝试发现需要哪个虚拟页面。通常一个硬件寄存器包含了这一信息,如果没有的话,操作系统必须检索程序计数器,取出这条指令,用软件分析这条指令,看看它在缺页中断时正在做什么。

④:一旦中断了发生缺页中断的虚拟地址,操作系统检查这个地址是否有效,并检查存取与保护是否一致。如果不一致,向进程发出一个信号或杀掉该进程。如果地址有效且没有保护错误发生,系统则检查是否有空闲页框。如果没有空闲页框,执行页面置换算法寻找一个页面来淘汰。

⑤:如果选择的页框“脏”了,安排该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程,让其他进程运行直至磁盘传输结束。无论如何,该页框被标记为忙,以免因为其他原因而被其他进程占用。

⑥:一旦页框“干净”后(无论是立刻还是在写回磁盘后),操作系统查找所需页面在磁盘上的地址通过磁盘操作将其装入。该页面被装入后,产生缺页中断的进程仍被挂起,并且如果有其他可运行的用户进程,则选择另一个用户进程运行。

⑦:当磁盘中断发生时,表明该项已经被装入,页表已经更新可以反映他的位置,页框也被标记为正常状态。

⑧:恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。

⑨:调度引发缺页中断的进程,操作系统返回调用它的汇编语言例程。

⑩:该例程恢复寄存器和其他状态信息,返回到用户空间继续执行,就好像缺页中断没有发生过一样。

 

13.分页与分段比较:

 

 

 

《现代操作系统》引论、进程与线程

1.操作系统是管理计算机硬件资源,控制其他程序运行并为用户提供交互操作界面的系统软件的集合。

 

2.多线程不提供真正的并行处理。在一个时刻一个CPU只有一个进程在运行,但是线程的切换时间则减少到纳秒数量级。

 

3.RAM:RamdomAccessMemory易挥发性随机存取存储器,高速存取,读写时间相等,且与地址无关,如计算机内存等。

 

4.ROM:Read Only Memory只读存储器。断电后信息不丢失,如计算机启动用的BIOS芯片。存取速度很低,(较RAM而言)且不能改写。由于不能改写信息,不能升级,现已很少使用。

 

5.在任意一个给定臂的位置,每个磁头可以读取一段环形区域,称为磁道。把一个给定臂的位置上的所有磁道合并起来,责成了一个柱面。每个磁道划分为若干扇区,扇区的典型值是512字节。在现代磁盘中,教外面的柱面比较内部的柱面有更多的扇区。

 

 

 

6.总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束, 按照计算机所传输的信息种类,计算机的总线可以划分为数据总线、地址总线和控制总线,分别用来传输数据、数据地址和控制信号。总线是一种内部结构,它是cpu、内存、输入、输出设备传递信息的公用通道,主机的各个部件通过总线相连接,外部设备通过相应的接口电路再与总线相连接,从而形成了计算机硬件系统。

 

7.BIOS(Basic Input Output System),基本输入输出系统。BIOS通过尝试储存在CMOS储存器中的设备清单决定启动设备。如果系统从硬盘启动,那么启动设备的第一个扇区被读入内存并执行。这个扇面中包含一个对保存在启动扇面末尾的分区表检查的程序,以确定哪个分区是活动的。然后,从该分区读入第二个启动装载模块。来自活动分区的这个装载模块被读入操作系统,并启动之。

 

8.进程本质上是正在执行的一个程序。与每个进程相关的是进程的地址空间。在许多操作系统中,与一个进程有关的所有信息,除了该进程自身地址空间的内容以外,均存放在操作系统的一张表中,称为进程表,进程表是数组(或链表)结构,当前存在的每个进程都要占用其中一项。

 

9.若一个进程能够创建一个或多个进程(称为子进程),而且这些进程又可以创建子进程,则很容易得到进程树。

 

 

 

进程A创建两个子进程B和C,进程B创建三个子进程D、E和F

 

10.系统管理器授予每个进程使用一个给定的UID标识,每个被启动的进程都有一个启动该进程的用户UID,子进程拥有与父进程一样的UID,用户可以是某个组的成员,每个组也有一个GID标识。

 

11.进程和文件层次都可以组织成树状结构,但这两种树状结构有不少不同之处。一般进程的树状结构层次不深(很少超过三层),而文件树状结构的层次常常多于四层、五层或更多层。进程树层次结构是暂时的,通常最多存在几分钟,而目录层次则可能存在数年之久。进程和文件在所有权及保护方面也是有区别的。典型的,只有父进程能控制和访问子进程,而在文件和目录中通常存在一种机制,使文件所有者之外的其他用户也可以访问该文件。

 

12.在MS-DOS和windows中,用反斜线( \ )字符作为分隔符,而在UNIX中使用正斜线( / )。

 

13.在UNIX中的另一个重要概念是安装文件系统。在mount调用之前,根文件系统在硬盘上,而第二个文件系统在CD-ROM上,他们是分离的和无关的。mount系统调用允许把CD-ROM上的文件系统连接到程序所希望的根文件系统上。

 

14.管道。管道pipe是一种虚文件,它可连接两个进程。

 

15.UNIX操作系统通过对每个文件赋予一个9位的二进制保护代码,对UNIX的文件实现保护。该保护代码有三个3位字段,一个用于所有者,一个用于所有者同组(用户被系统管理员划分成组)中的其他成员,而另一个用于其他人。每个字段中有一位用于读访问,一位用于写访问,一位用于执行访问。这些位就是知名的rwx位。

 

16.在UNIX中,fork是唯一可以在POSIX创建进程的途径。它创建一个原有进程的精确副本,包括所有的文件描述符,寄存器等全部内容。在fork之后,原有的进程及其副本(父与子)就分开了。在fork时,所有的变量具有一样的值。虽然父进程的数据被复制用以创建子进程,但是其中一个的后续变化并不会影响到另一个。(由父进程和子进程共享的程序正文,是不可改变的)fork调用返回一个值,在子进程中该值为0,并且等于子进程的进程标识符,或等于父进程中PID。使用被返回的PID,就可以在两个进程中看出哪一个是父进程,哪一个是子进程。

    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值;

 

17.在UNIX的进程将其存储空间划分为三段:正文段(如程序代码)、数据段(如变量)以及堆栈段。数据段向上增长而堆栈段向下增长。

 

18.在windows中没有类似UNIX中的进程层次,所以不存在父进程和子进程的概念。

 

19.有4种主要事件导致进程的创建:

①:系统初始化

②:执行了正在运行的进程所调用的进程创建系统调用

③:用户请求创建一个新的进程

④:一个批处理作业的初始化

 

20.守护进程是生存期长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。他们常常在系统引导装入时启动,在系统关闭时终止。unix系统有很多守护进程,大多数服务器都是用守护进程实现的。比如,网络服务inetd、Web服务http等。同时,守护进程完成许多系统任务。比如,作业规划进程crond、打印进程lqd等。

 

21.在UNIX和Windows中,进程创建之后,父进程和子进程有各自不同的地址空间。

 

22.以下条件会引起进程的退出:

①:正常退出(自愿的)

②:出错退出(自愿的)

③:严重退出(非自愿)

④:被其他进程杀死(非自愿)

 

23.windows中没有进程层次概念,所有的进程都是地位相同的。创建进程的时候,父进程得到一个特别的令牌(称为句柄),该句柄可以用来控制子进程。但是他有权把这个令牌传送给某个其他进程,这样就不存在进程层次了。在UNIX中,进程就不能剥夺其子女的“继承权”。

 

24.进程的三种状态:

①:运行态(该时刻进程实际占用CPU)

②:就绪态(可运行,但因为其他进程正在运行而暂时停止)

③:阻塞态(除非某种外部事件发生,否则进程不能运行)

 

1:就绪->执行, 调度程序选择这个进程
2:执行->就绪, 调度程序选择另一个进程

3:执行->阻塞, 进程为等待输入而阻塞

4:阻塞->就绪, 出现有效输入

 

25.为了实现进程模型,操作系统维护着一张表格(一个结构数组),即进程表。每个进程用一个进程表项。(有些作者称这些表项为进程控制块)。该表项包含了进程状态的重要信息,包含程序计数器、堆栈指针、内存分配状况、所打开文件的状态、账号和调度信息、以及其他在进程由运行状态转换到就绪态或阻塞态时必保存的信息。

 

 

 

 

26.进程中不同的线程不像不同的进程一样有很大的独立性,所有的线程都有完全一样的地址空间。线程也有运行、阻塞、就绪或终止状态。每一个线程都有自己的堆栈。常见的线程调用时thread_yield,它运行线程自动放弃CPU从而让另一个线程运行。

 

27.在用户空间实现线程和在内核中实现线程:

  

 

 

 

线程表的位置:一个在进程中、一个在内核。

 

28.信号是给进程的而不是给线程的。

 

29.一个消息的到达导致系统创建一个处理该消息的线程,这种线程称为弹出式线程。

 

30.进程间通信:

1.竞争条件:即两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,称为竞争条件。

2.临界区:

互斥:即以某种手段确保当一个进程在使用一个共享变量或文件时,其他进程不能做同样的操作。

我们把对共享内存进行访问的程序片段称作临界区域或临界区。

为了避免对临界区的竞争条件,保证使用共享数据的并发进程能够正确和高效的进行协作,一个好的解决方案,必须满足:

①:任何两个进程不能同时处于其临界区

②:不应对CPU的速度和数量做任何假设

③:临界区外运行的进程不得阻塞其他进程

④:不得使进程无限期等待进入临界区

 

 

 

31.忙等待的互斥

1.屏蔽中断

屏蔽中断后CPU将不会被切换到其他进程,于是,一旦某个进程屏蔽中断之后,它就可以检查和修改共享内存,而不必担心其他进程进入。屏蔽中断只对执行disable指令的CPU有效,其他CPU仍将继续运行。

2.锁变量

当一个进程想进入其临界区时,它首先测试这把锁。如果该锁的值为0,则该进程将其设置为1并进入临界区。若这把锁的值已经为1,则该进程将等待直到其值为0.于是,0就表示临界区内没有进程,1表示已经有某个进程进入临界区。这种方法同样会发生竞争条件。

3.严格轮换法

连续测试一个变量直到某个值出现为止,称为忙等待。只有在有理由认为是非常短的情况下,才使用忙等待,用于忙等待的锁,称为自旋锁。

4.Peterson解法

代码1

5.TSL指令

TSL RX,LOCK    测试并加锁,执行TSL指令的CPU将锁住内存总线,以禁止其他CPU在本指令结束之前访问内存。

 

 

 

 

32.睡眠与唤醒

忙等待不仅浪费了CPU时间,而且还可能引起预想不到的结果。考虑一台计算机有两个进程,H优先级高,L优先级较低。调度规则规定,只要H处于就绪态它就可以运行。在某一时刻,L处于临界区中,此时H变到就绪态,准备运行。现在H开始忙等待,但由于当H就绪时L不会被调度,也就无法离开临界区,所以H将永远忙等待下去,这种情况有时被称作优先级反转问题

最简单的是sleep和wakeup。sleep是一个将引起调用进程阻塞的系统调用,即将被挂起,直到另外一个进程将其唤醒。wakeup调用有一个参数,即要被唤醒的进程。另一种方法是让sleep和wakeup各有一个参数,即有一个用于匹配sleep和wakeup的内存地址。

 

33.生产者-消费者问题

 

 

 

 

34.信号量:信号量是最早出现的用来解决进程同步与互斥问题的机制(也可实现进程通信),包括一个称为信 号量的变量及对它进行的两个原语操作。信号量为一个整数,我们设这个信号量为:sem。很显然,我们规定在sem大于等于零的时候代表可供并发进程使用的 资源实体数,sem小于零的时候,表示正在等待使用临界区的进程的个数。根据这个原则,在给信号量附初值的时候,我们显然就要设初值大于零。

首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:

             P(S):①将信号量S的值减1,即S=S-1;

                    ②如果S>=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。

             V(S):①将信号量S的值加1,即S=S+1;

                    ②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。

使用PV操作实现进程互斥时应该注意的是:

1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。

2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。

3)互斥信号量的初值一般为1。

利用信号量和PV操作实现进程同步:

PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。

信号量、PV操作是解决进程间的同步与互斥问题的。

★     做题时尤其要注意隐藏的同步、互斥问题。这些问题通常可以归入生产者-消费者问题和阅读者-写入者问题。

★     PV操作一定是成对出现的,但是这不意味着它会在一个进程内成对出现。

★     在互斥关系中,PV操作一定是在一个进程内成对出现。而且,信号一定大于0,具体多少视情况而定。而对于同步关系,则一对PV操作在两个进程或者更多的进程中出现。

★     对于同步关系,信号量可能为0,也可能不为0;用于同步的信号个数可能1个,也可能是多个。

★     在生产者-消费者问题中,要设置三个信号量:empty-空闲的缓存区数量,初值为n;full-已填充的缓存区数量,初值为0;mutex-保证只有一个进程在写入缓存区,初值为1。

★     在阅读者-写入者问题中,设置两个信号量:信号量access-控制写入互斥,初值为1;信号量rc-控制对共享变量ReadCount(读者统计值)的互斥访问。

 

35.互斥量:互斥量表现互斥现象的数据结构,也被当作二元信号灯。一个互斥基本上是一个多任务敏感的二元信号,它能用作同步多任务的行为,它常用作保护从中断来的临界段代码并且在共享同步使用的资源。

Mutex 本质上说就是一把锁,提供对资源的独占访问,所以Mutex主要的作用是用于互斥。Mutex对象的值,只有0和1两个值。这两个值也分别代表了 Mutex的两种状态。值为0, 表示锁定状态,当前对象被锁定,用户进程/线程如果试图Lock临界资源,则进入排队等待;值为1,表示空闲状态,当前对象为空闲,用户进程/线程可以 Lock临界资源,之后Mutex值减1变为0。

Mutex可以被抽象为四个操作:

- 创建 Create

- 加锁 Lock

- 解锁 Unlock

- 销毁 Destroy

Mutex被创建时可以有初始值,表示Mutex被创建后,是锁定状态还是空闲状态。在同一个线程中,为了防止死锁,系统不允许连续两次对Mutex加锁(系统一般会在第二次调用立刻返回)。也就是说,加锁和解锁这两个对应的操作,需要在同一个线程中完成。

 

互斥量值只能为0/1,信号量值可以为非负整数。

互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

 

36.条件变量:与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止通常条件变量和互斥锁同时使用。

条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”(给出条件成立信号)。

条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。

 

37.管程:管程的基本思想是,将共享变量和对它们的操作集中在一个模块中,操作系统或并发程序就由这样的模块构成。这样模块之间联系清晰,便于维护和修改,易于保证正确性。
    从语言的角度看,管程主要有以下特性:
  (1)模块化。管程是一个基本程序单位,可以单独编译; 
  (2)抽象数据类型。管程是中不仅有数据,而且有对数据的操作; 
  (3)信息掩蔽。管程外可以调用管程内部定义的一些函数,但函数的具体实现外部不可见; 
    对于管程中定义的共享变量的所有操作都局限在管程中,外部只能通过调用管程的某些函数来间接访问这些变量。因此管程有很好的封装性。管程通常是用于管理资源的,因此管程中有进程等待队列和相应的等待和唤醒操作。

 

38.消息传递:这种进程间通信的方法使用两条原语send和receive,他们像信号量而不像管程,是系统调用而不是语言成分。因此可以很容易将他们加入到库例程中去,如:

send(destination, &message);         和          receive(source, &message);

消息传递设计:一旦接受到信息,接收方马上回送一条特殊的确认消息,如果发送方在一段时间内未收到确认,则重发信息。

 

39.调度:在操作系统中,完成选择工作的这一部分称为调度程序,该程序使用的算法称为调度算法。

某些进程花费了绝大多数时间在计算上,而其他进程则在等待I/O上花费了绝大多数时间。前者称为计算密集型,后者称为I/O密集型。

两类调度算法:

非抢占式调度算法:挑选一个进程,然后让该进程运行直至被阻塞(阻塞在I/O上或等待另一个进程),或者直至该进程自动释放CPU。

抢占式调度算法:挑选一个进程,并且让该进程运行某个固定时段的最大值。如果在该时段结束时,该进程仍在运行,他就会被挂起,而调度算法会选择另一个进程运行。

调度算法分类:

批处理,交互式,实时

 

吞吐量:是系统每小时完成的作业数量。

周转时间:是指从一个批处理作业开始直到作业完成时刻为止的统计平均时间。

 

批处理系统中的调度:

1.先来先服务:以队列的形式,先来的作业先执行。

2.最短作业优先:预测最短的作业然后选择最短的作业先运行。

3.最短剩余时间优先:当前剩下时间最少的先运行。

 

交互式系统中的调度:

1.轮转调度:每个进程被分配一个时间片,时间片结束时,若还在运行,则分配给另一个进程。

时间片设得太短会导致过多的进程切换,降低了CPU效率,而设得太长又可能引起对短的交互请求的响应时间变长。将时间片设为20ms-50ms通常是一个比较合理的折中。

2.优先级调度:优先级高的可运行进程先运行。调度程序会在每个时钟滴答(即每个时钟中断)降低当前进程的优先级。

3.多级队列:设立优先级类。属于最高优先级的进程运行一个时间片,属于次高优先级类的进程运行2个时间片,再次一级运行4个时间片,依次类推。当一个进程用完分配的时间片后,它被移到下一类。

4.最短进程优先:优先运行可运行进程中最短的那个进程。

5.保证调度:若所有进程都等价,则每个进程获得1/n的CPU时间。

6.彩票调度:向进程提供各种系统资源的彩票,一旦要做出决策时,随机抽出一张彩票,拥有该彩票的进程获得该资源。

7.公平分享调度:不考虑用户,每个进程都将获得等价的CPU时间片。

 

用户级线程和内核级线程之间的差别在于性能,用户级线程的线程切换需要少量的机器指令,而内核级线程需要完整的上下文切换。

posted @ 2020-05-28 15:30  CharyGao  阅读(918)  评论(0编辑  收藏  举报