Fork me on GitHub
操作系统设计与实现:深入解析

《Operation System Design and Implementation》(中文名:《操作系统设计与实现》)这本书可以说是讲述操作系统原理的经典之作,但令人意犹未尽的是,书中的内容多侧重于“如何做”,而对“为什么要这么做”往往只有寥寥数语。本文及后续的文章试图从更深入的层次去解析书中的内容,与各位共探讨。我假定您读过这本书,并对书中的内容有一定的熟悉程度,因此对书中原有内容将不再重复。后面的内容均基于该书英文版第三版。在必要的时候我会列出和我所写内容相关的书的章节号。

第一篇 关于临界段(原书相关内容:Section 2.2.3)

先看书的作者给出的解决critical region问题的两段程序:

复制代码
while(TRUE) {    
    while(turn != 0);    
    critical_region();    
    turn = 1;   
    noncritical_region();
}
复制代码
复制代码
while(TRUE) {   
    while(turn != 1);    
    critical_region();    
    turn = 0;    
    noncritical_region();
}
复制代码

这可以说是解决critical region问题的一个最简方案——不需要特别的硬件支持(不需要CPU有lock类指令)。尽管该方案存在着一些不好的限制(例如两个process只能且必须轮流进入critical region),但我们可以将该解决方案做为讨论问题的起点。

在看过书的作者给出的对以上代码的解释过后,有几个问题自然浮现于脑海:

1. 该方案解决critical region的基本原理是什么?

2. 是否可将该方案推广到任意个process?

3. 是否可以对其进行修改,以解决必须轮流进critical region的问题?

对第一个问题,我们仔细看一下turn变量。两个process进入critical region都会检测turn的值是否为0/1,而在退出critical region时会将turn设置为1/0。如果您曾了解过令牌环网,您也许就会想到,turn在此处实际上相当于一个令牌。两个process在进入critical region之前需要先获取令牌(检测turn为0/1),退出critical region时将该令牌释放(设置turn为1/0)。想到此处,问题2,3就迎刃而解了:

解答2. 将其推广到任意个process

假定我们有N个process,仍然将turn当作令牌来用,为每个process分配一个令牌ID (0~N-1),那么进程n就有如下代码:

复制代码
while(TRUE) {
   while(turn != n);    // 等待令牌
    critical_region();
turn
= (n+1) % N; // 将令牌交给下一个进程 noncritical_region(); }
复制代码

 解答3. 如果某个不需要进入critical region的进程得到了令牌,那么只需将令牌直接交给下一个进程即可。相关代码就不详细列出了。

 
分类: 操作系统
posted on 2012-12-11 16:10  HackerVirus  阅读(369)  评论(0编辑  收藏  举报