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:
parent
93aa027f21
commit
be0ccbe301
@ -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`互斥锁同步是比较低级的做法。我们现在改用无缓存的管道来实现同步:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user