mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-11-13 09:16:10 +08:00
精校:9.2-9.4
This commit is contained in:
@@ -8,22 +8,41 @@
|
||||
|
||||
在 Go 语言中这种锁的机制是通过 sync 包中 Mutex 来实现的。sync 来源于 "synchronized" 一词,这意味着线程将有序的对同一变量进行访问。
|
||||
|
||||
sync.Mutex 是一个互斥锁,它的作用是守护在临界区入口来确保同一时间只能有一个线程进入临界区。
|
||||
`sync.Mutex` 是一个互斥锁,它的作用是守护在临界区入口来确保同一时间只能有一个线程进入临界区。
|
||||
|
||||
假设 info 是一个需要上锁的放在共享内存中的变量。通过包含 Mutex 来实现的一个典型例子如下:
|
||||
假设 info 是一个需要上锁的放在共享内存中的变量。通过包含 `Mutex` 来实现的一个典型例子如下:
|
||||
|
||||
```go
|
||||
import “sync”
|
||||
import “sync”
|
||||
|
||||
type Info struct {
|
||||
mu sync.Mutex
|
||||
// ... other fields, e.g.: Str string
|
||||
}
|
||||
```
|
||||
|
||||
如果一个函数想要改变这个变量可以这样写:
|
||||
|
||||
```go
|
||||
func Update(info *Info) {
|
||||
mu sync.Mutex
|
||||
// ... other fields, e.g.: Str string
|
||||
info.mu.Lock()
|
||||
// critical section:
|
||||
info.Str = // new value
|
||||
// end critical section
|
||||
info.mu.Unlock()
|
||||
}
|
||||
```
|
||||
|
||||
还有一个很有用的例子是通过 Mutex 来实现一个可以上锁的共享缓冲器:
|
||||
|
||||
```go
|
||||
type SyncedBuffer struct {
|
||||
lock sync.Mutex
|
||||
buffer bytes.Buffer
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
在 sync 包中还有一个 `RWMutex` 锁:他能通过 `RLock()` 来允许同一时间多个线程对变量进行读操作,但是只能一个线程进行写操作。如果使用 `Lock()` 将和普通的 `Mutex` 作用相同。包中还有一个方便的 `Once` 类型变量的方法 `once.Do(call)`,这个方法确保被调用函数只能被调用一次。
|
||||
|
||||
相对简单的情况下,通过使用 sync 包可以解决同一时间只能一个线程访问变量或 map 类型数据的问题。如果这种方式导致程序明显变慢或者引起其他问题,我们要重新思考来通过 goroutines 和 channels 来解决问题,这是在 Go 语言中所提倡用来实现并发的技术。我们将在第 14 章对其深入了解,并在第 14.7 节中对这两种方式进行比较。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user