第9章,部分字词修订。

This commit is contained in:
zhliner
2017-08-24 22:30:37 +08:00
parent 69606d498b
commit c8ef4d39ea
9 changed files with 21 additions and 22 deletions

View File

@@ -1,12 +1,12 @@
## 9.1. 竞争条件
在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话)以此类推。在有两个或更多goroutine的程序中每一个goroutine内的语句也是按照既定的顺序去执行的但是一般情况下我们没法去知道分别位于两个goroutine的事件x和y的执行顺序x是在y之前还是之后还是同时发生是没法判断的。当我们能够没有办法自信地确认一个事件是在另一个事件的前面或者后面发生的话就说明x和y这两个事件是并发的。
在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话)以此类推。在有两个或更多goroutine的程序中每一个goroutine内的语句也是按照既定的顺序去执行的但是一般情况下我们没法去知道分别位于两个goroutine的事件x和y的执行顺序x是在y之前还是之后还是同时发生是没法判断的。当我们没有办法自信地确认一个事件是在另一个事件的前面或者后面发生的话就说明x和y这两个事件是并发的。
考虑一下,一个函数在线性程序中可以正确地工作。如果在并发的情况下,这个函数依然可以正确地工作的话,那么我们就说这个函数是并发安全的,并发安全的函数不需要额外的同步工作。我们可以把这个概念概括为一个特定类型的一些方法和操作函数,对于某个类型来说,如果其所有可访问的方法和操作都是并发安全的话,那么类型便是并发安全的。
在一个程序中有非并发安全的类型的情况下我们依然可以使这个程序并发安全。确实并发安全的类型是例外而不是规则所以只有当文档中明确地说明了其是并发安全的情况下你才可以并发地去访问它。我们会避免并发访问大多数的类型无论是将变量局限在单一的一个goroutine内还是用互斥条件维持更高级别的不变性都是为了这个目的。我们会在本章中说明这些术语。
在一个程序中有非并发安全的类型的情况下我们依然可以使这个程序并发安全。确实并发安全的类型是例外而不是规则所以只有当文档中明确地说明了其是并发安全的情况下你才可以并发地去访问它。我们会避免并发访问大多数的类型无论是将变量局限在单一的一个goroutine内还是用互斥条件维持更高级别的不变性都是为了这个目的。我们会在本章中说明这些术语。
相反,导出包级别的函数一般情况下都是并发安全的。由于package级的变量没法被限制在单一的gorouine所以修改这些变量“必须”使用互斥条件。
相反,包级别的导出函数一般情况下都是并发安全的。由于package级的变量没法被限制在单一的gorouine所以修改这些变量“必须”使用互斥条件。
一个函数在并发调用时没法工作的原因太多了,比如死锁(deadlock)、活锁(livelock)和饿死(resource starvation)。我们没有空去讨论所有的问题,这里我们只聚焦在竞争条件上。
@@ -114,7 +114,7 @@ func Icon(name string) image.Image { return icons[name] }
第二种避免数据竞争的方法是避免从多个goroutine访问变量。这也是前一章中大多数程序所采用的方法。例如前面的并发web爬虫(§8.6)的main goroutine是唯一一个能够访问seen map的goroutine而聊天服务器(§8.10)中的broadcaster goroutine是唯一一个能够访问clients map的goroutine。这些变量都被限定在了一个单独的goroutine中。
由于其它的goroutine不能够直接访问变量它们只能使用一个channel来发送给指定的goroutine请求来查询更新变量。这也就是Go的口头禅“不要使用共享数据来通信使用通信来共享数据”。一个提供对一个指定的变量通过channel来请求的goroutine叫做这个变量的监控(monitor)goroutine。例如broadcaster goroutine会监控(monitor)clients map的全部访问。
由于其它的goroutine不能够直接访问变量它们只能使用一个channel来发送请求给指定的goroutine来查询更新变量。这也就是Go的口头禅“不要使用共享数据来通信使用通信来共享数据”。一个提供对一个指定的变量通过channel来请求的goroutine叫做这个变量的monitor(监控)goroutine。例如broadcaster goroutine会监控clients map的全部访问。
下面是一个重写了的银行的例子这个例子中balance变量被限制在了monitor goroutine中名为teller