Skip to content

Commit 790df29

Browse files
committed
fix typos
1 parent b8ad233 commit 790df29

File tree

2 files changed

+2
-2
lines changed

2 files changed

+2
-2
lines changed

source/chapter8/4condition-variable.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
100100
管程有一个很重要的特性,即任一时刻只能有一个活跃线程调用管程中过程,这一特性使线程在调用执行管程中过程时能保证互斥,这样线程就可以放心地访问共享变量。管程是编程语言的组成部分,编译器知道其特殊性,因此可以采用与其他过程调用不同的方法来处理对管程的调用,比如编译器可以在管程中的每个过程的入口/出口处加上互斥锁的加锁/释放锁的操作。因为是由编译器而非程序员来生成互斥锁相关的代码,所以出错的可能性要小。
101101

102-
管程虽然借助编译器提供了一种实现互斥的简便途径,但这还不够,还需要一种线程间的沟通机制。首先是等待机制:由于线程在调用管程中某个过程时,发现某个条件不满足,那就在无法继续运行而被阻塞。这里需要注意的是:在阻塞之前,操作系统需要把进入管程的过程入口出的互斥锁给释放掉,这样才能让其他线程有机会调用管程的过程。
102+
管程虽然借助编译器提供了一种实现互斥的简便途径,但这还不够,还需要一种线程间的沟通机制。首先是等待机制:由于线程在调用管程中某个过程时,发现某个条件不满足,那就在无法继续运行而被阻塞。这里需要注意的是:在阻塞之前,操作系统需要把进入管程的过程入口处的互斥锁给释放掉,这样才能让其他线程有机会调用管程的过程。
103103

104104
其次是唤醒机制:另外一个线程可以在调用管程的过程中,把某个条件设置为真,并且还需要有一种机制及时唤醒等待条件为真的阻塞线程。这里需要注意的是:唤醒线程(本身执行位置在管程的过程中)如果把阻塞线程(其执行位置还在管程的过程中)唤醒了,那么需要避免两个活跃的线程都在管程中导致互斥被破坏的情况。为了避免管程中同时有两个活跃线程,我们需要一定的规则来约定线程发出唤醒操作的行为。目前有三种典型的规则方案:
105105

source/chapter8/5concurrency-problem.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ A是共享变量。粗略地看,可以估计执行流程为:第一个线程t
8888
...
8989
}
9090
91-
A是共享变量。粗略地看,可以估计执行流程为:线程thr1先被创建,等了10ms后,线程thr2再被创建。一般情况下,这就导致了thr1先于thr2执行,即第5行会先于第10行执行,得到预期的结果。但可能出现一种执行情况:线程thr1在执行第5句前,由于某种原因进入了休眠,导致线程thr2执行第10行在前,线程th1执行第5行在后,导致获得非预期的错误结果。
91+
A是共享变量。粗略地看,可以估计执行流程为:线程thr1先被创建,等了10ms后,线程thr2再被创建。一般情况下,这就导致了thr1先于thr2执行,即第5行会先于第9行执行,得到预期的结果。但可能出现一种执行情况:线程thr1在执行第5句前,由于某种原因进入了休眠,导致线程thr2执行第10行在前,线程th1执行第5行在后,导致获得非预期的错误结果。
9292

9393
这里出现问题的根源是线程在对共享变量进行访问时,违反了临界区的预期顺序原则。解决这样的问题需要给线程的相关代码位置加上同步操作(如通过信号量或条件变量等),确保线程间的执行顺序符合预期,修改后的代码如下:
9494

0 commit comments

Comments
 (0)