1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-23 20:02:22 +00:00

1.6 Unlock 拼写修正

This commit is contained in:
jiayx 2018-01-15 10:32:43 +08:00
parent 93aa027f21
commit be0ccbe301

View File

@ -30,7 +30,7 @@ func main() {
}
```
因为`mu.Lock()``mu.Unock()`并不在同一个Goroutine中所以也就不满足顺序一致性内存模型。同时它们也没有其它的同步事件可以参考这两个事件不可排序也就是可以并发的。因为可能是并发的事件所以`main`函数中的`mu.Unock()`很有可能先发生,而这个时刻`mu`互斥对象还处于未加锁的状态,从而会导致运行时异常。
因为`mu.Lock()``mu.Unlock()`并不在同一个Goroutine中所以也就不满足顺序一致性内存模型。同时它们也没有其它的同步事件可以参考这两个事件不可排序也就是可以并发的。因为可能是并发的事件所以`main`函数中的`mu.Unlock()`很有可能先发生,而这个时刻`mu`互斥对象还处于未加锁的状态,从而会导致运行时异常。
下面是修复后的代码:
@ -41,14 +41,14 @@ func main() {
mu.Lock()
go func(){
fmt.Println("你好, 世界")
mu.Unock()
mu.Unlock()
}()
mu.Lock()
}
```
修复的方式是在`main`函数所在线程中执行两次`mu.Lock()`,当第二次加锁时会因为锁已经被占用(不是递归锁)而阻塞,`main`函数的阻塞状态驱动后台线程继续向前执行。当后台线程执行到`mu.Unock()`时解锁,此时打印工作已经完成了,解锁会导致`main`函数中的第二个`mu.Lock()`阻塞状态取消,此时后台线程和主线程再没有其它的同步事件参考,它们退出的事件将是并发的:在`main`函数退出导致程序退出时,后台线程可能已经退出了,也可能没有退出。虽然无法确定两个线程退出的时间,但是打印工作是可以正确完成的。
修复的方式是在`main`函数所在线程中执行两次`mu.Lock()`,当第二次加锁时会因为锁已经被占用(不是递归锁)而阻塞,`main`函数的阻塞状态驱动后台线程继续向前执行。当后台线程执行到`mu.Unlock()`时解锁,此时打印工作已经完成了,解锁会导致`main`函数中的第二个`mu.Lock()`阻塞状态取消,此时后台线程和主线程再没有其它的同步事件参考,它们退出的事件将是并发的:在`main`函数退出导致程序退出时,后台线程可能已经退出了,也可能没有退出。虽然无法确定两个线程退出的时间,但是打印工作是可以正确完成的。
使用`sync.Mutex`互斥锁同步是比较低级的做法。我们现在改用无缓存的管道来实现同步: