修正半角标点符号

This commit is contained in:
kimw
2018-06-09 16:36:07 +00:00
parent a81bfabcdc
commit 7ebd75aeae
60 changed files with 132 additions and 132 deletions
+5 -5
View File
@@ -6,7 +6,7 @@
var icons map[string]image.Image
```
这个版本的Icon用到了懒初始化(lazy initialization)
这个版本的Icon用到了懒初始化lazy initialization
```go
func loadIcons() {
@@ -41,7 +41,7 @@ func loadIcons() {
}
```
因此,一个goroutine在检查icons是非空时,也并不能就假设这个变量的初始化流程已经走完了(译注:可能只是塞了个空map,里面的值还没填完,也就是说填值的语句都没执行完呢)
因此,一个goroutine在检查icons是非空时,也并不能就假设这个变量的初始化流程已经走完了译注:可能只是塞了个空map,里面的值还没填完,也就是说填值的语句都没执行完呢
最简单且正确的保证所有goroutine能够观察到loadIcons效果的方式,是用一个mutex来同步检查。
@@ -87,7 +87,7 @@ func Icon(name string) image.Image {
```
上面的代码有两个临界区。goroutine首先会获取一个读锁,查询map,然后释放锁。如果条目被找到了(一般情况下),那么会直接返回。如果没有找到,那goroutine会获取一个写锁。不释放共享锁的话,也没有任何办法来将一个共享锁升级为一个互斥锁,所以我们必须重新检查icons变量是否为nil,以防止在执行这一段代码的时候,icons变量已经被其它gorouine初始化过了。
上面的代码有两个临界区。goroutine首先会获取一个读锁,查询map,然后释放锁。如果条目被找到了一般情况下,那么会直接返回。如果没有找到,那goroutine会获取一个写锁。不释放共享锁的话,也没有任何办法来将一个共享锁升级为一个互斥锁,所以我们必须重新检查icons变量是否为nil,以防止在执行这一段代码的时候,icons变量已经被其它gorouine初始化过了。
上面的模板使我们的程序能够更好的并发,但是有一点太复杂且容易出错。幸运的是,sync包为我们提供了一个专门的方案来解决这种一次性初始化的问题:sync.Once。概念上来讲,一次性的初始化需要一个互斥量mutex和一个boolean变量来记录初始化是不是已经完成了;互斥量用来保护boolean变量和客户端数据结构。Do这个唯一的方法需要接收初始化函数作为其参数。让我们用sync.Once来简化前面的Icon函数吧:
@@ -101,6 +101,6 @@ func Icon(name string) image.Image {
}
```
每一次对Do(loadIcons)的调用都会锁定mutex,并会检查boolean变量(译注:Go1.9中会先判断boolean变量是否为1(true),只有不为1才锁定mutex,不再需要每次都锁定mutex)。在第一次调用时,boolean变量的值是falseDo会调用loadIcons并会将boolean变量设置为true。随后的调用什么都不会做,但是mutex同步会保证loadIcons对内存(这里其实就是指icons变量啦)产生的效果能够对所有goroutine可见。用这种方式来使用sync.Once的话,我们能够避免在变量被构建完成之前和其它goroutine共享该变量。
每一次对Do(loadIcons)的调用都会锁定mutex,并会检查boolean变量译注:Go1.9中会先判断boolean变量是否为1(true),只有不为1才锁定mutex,不再需要每次都锁定mutex。在第一次调用时,boolean变量的值是falseDo会调用loadIcons并会将boolean变量设置为true。随后的调用什么都不会做,但是mutex同步会保证loadIcons对内存这里其实就是指icons变量啦产生的效果能够对所有goroutine可见。用这种方式来使用sync.Once的话,我们能够避免在变量被构建完成之前和其它goroutine共享该变量。
**练习 9.2** 重写2.6.2节中的PopCount的例子,使用sync.Once,只在第一次需要用到的时候进行初始化。(虽然实际上,对PopCount这样很小且高度优化的函数进行同步可能代价没法接受)
**练习 9.2** 重写2.6.2节中的PopCount的例子,使用sync.Once,只在第一次需要用到的时候进行初始化。虽然实际上,对PopCount这样很小且高度优化的函数进行同步可能代价没法接受。)