diff --git a/thu_os/chp17.md b/thu_os/chp17.md index 2a12892..b2486e2 100644 --- a/thu_os/chp17.md +++ b/thu_os/chp17.md @@ -148,7 +148,7 @@ flag[i] = false; ## 高级抽象方法 -高级抽象方法是操作系统提供的编程抽象,以简化进程之间资源互斥访问的解决方案的。为什么叫高级抽象方法呢?回顾前面的软件方法,我们自己设计的那几种算法均不奏效,其本质原因是进程在检查标志和设置标志之间可能会被打断,被操作系统调度。当操作系统介入进程之间的互斥访问时,就提供一些高级编程抽象,使得这些操作可以不被打断地执行,即原子操作。 +高级抽象方法是操作系统提供的编程抽象,以简化进程之间资源的互斥访问。为什么叫高级抽象方法呢?回顾前面的软件方法,我们自己设计的那几种算法均不奏效,其本质原因是进程在检查标志和设置标志之间可能会被打断,被操作系统调度。当操作系统介入进程之间的互斥访问时,就可以提供一些高级编程抽象,使得这些操作可以不被打断地执行,即原子操作。 高级抽象方法包括锁,信号量和条件变量。这里就只讨论锁机制,后面两种将在[进程管理(4):信号量与管程](chp18.md)中进行讨论。 @@ -182,7 +182,7 @@ void exchange(bool *a, bool *b){ } ``` -通过这两个原子操作指令可以实现锁机制,下面首先叙述如果通过`ts`指令来实现锁。 +通过这两个原子操作指令可以实现锁机制,下面首先叙述如何通过`ts`指令来实现锁。 > 使用原子指令实现自旋锁(`spin lock`) @@ -222,13 +222,13 @@ Lock::release(){ } ``` -可以看到,相对于前面的软件方法,引入了锁机制后可以方便地实现进程临界区的互斥访问,并且很容易可以证明该方法的正确性,并且可以适用于多处理器中任意数量的进程之间的互斥访问。 +可以看到,相对于前面的软件方法,引入了锁机制后可以方便地实现进程临界区的互斥访问,并且很容易可以证明该方法的正确性,还可以适用于多处理器中任意数量的进程之间的互斥访问。 当然,锁机制也具有一定的缺点,比如这里的等待仍然是忙等待,而不是`让权等待`。此外,也可能会出现饥饿和死锁的现象,比如低优先级进程占用资源,而高优先级进程占用CPU并且请求资源,此时两方互不相让就会出现死锁。关于死锁问题的解决会在后面[进程管理(5):死锁](chp20.md)中进行讨论。 > 利用`ts`指令实现无忙等待锁 -它的基本的思想和自旋锁是一样的,只是一旦进程不能进入临界区,则将它加入等待队列,并且进入阻塞状态。在一个进程释放了锁资源后,再挑选等待队列中的一个阻塞进程,并将它唤醒。具体的代码如下: +它的基本思想和自旋锁是一样的,只是一旦进程不能进入临界区,则将它加入等待队列,并且进入阻塞状态。在一个进程释放了锁资源后,再挑选等待队列中的一个阻塞进程,并将它唤醒。具体的代码如下: ```c Lock:acquire(){