在Go语言中,`sync`包提供了用于并发控制的工具和机制。这个包提供了互斥锁(Mutex)和条件变量(Cond)等基本的数据结构,以及一些其他用于同步的函数和类型。
以下是`sync`包中一些常用的并发控制工具及其使用方法:
1. 互斥锁(Mutex):
互斥锁用于保护共享资源,确保同一时间只有一个goroutine可以访问共享资源。通过使用`sync.Mutex`类型,可以控制对共享资源的访问。
示例:
```go
import "sync"
var mutex sync.Mutex // 定义一个互斥锁
func doSomething() {
mutex.Lock() // 加锁,阻止其他goroutine访问共享资源
// 执行对共享资源的操作
mutex.Unlock() // 解锁,允许其他goroutine访问共享资源
}
```
2. 读写锁(RWMutex):
读写锁允许多个goroutine同时读取共享资源,但只允许一个goroutine写入。这对于读操作远多于写操作的场景非常有用。
示例:
```go
import "sync"
var rwMutex sync.RWMutex // 定义一个读写锁
func readSomething() {
rwMutex.RLock() // 加读锁,允许多个goroutine同时读取共享资源
// 执行读取操作
rwMutex.RUnlock() // 解锁读锁
}
func writeSomething() {
rwMutex.Lock() // 加写锁,阻止其他goroutine读取或写入共享资源
// 执行写入操作
rwMutex.Unlock() // 解锁写锁
}
```
3. 等待组(WaitGroup):
`sync.WaitGroup`用于等待一组goroutine完成执行。它允许你等待一组并发执行的goroutine完成,然后继续执行其他操作。
示例:
```go
import "sync"
var wg sync.WaitGroup // 定义一个等待组
func doWork() {
wg.Add(1) // 增加等待组的计数器,表示有一个goroutine正在执行任务
// 执行任务逻辑...
wg.Done() // 表示任务完成,减少等待组的计数器
}
func main() {
for i := 0; i < 10; i++ { // 启动多个goroutine执行任务... } wg.Wait() // 等待所有goroutine完成执行 }`
4. 条件变量(Cond):`sync.Cond`用于在多个goroutine之间进行条件同步。它允许一个或多个goroutine在满足特定条件时被唤醒或阻塞。通常与互斥锁一起使用,以确保在修改条件时互斥访问共享资源。示例:```go import "sync" var mu sync.Mutex var cond = sync.NewCond(&mu) // 定义一个互斥锁和一个条件变量 func waitForSignal() { mu.Lock() // 加锁 defer mu.Unlock() // 在释放锁之前,使用条件变量等待信号 cond.Wait() // 等待信号 } func sendSignal() { mu.Lock() // 加锁 if someCondition { // 检查条件是否满足 mu.Unlock() // 如果条件满足,解锁并唤醒一个等待的goroutine return } // 其他逻辑 mu.Unlock() // 如果条件不满足,则继续其他逻辑 cond.Signal() // 发送信号 } ```在这个示例中,`waitForSignal`函数在满足某个条件之前会一直等待。当其他goroutine中的`sendSignal`函数检查到条件满足时,会通过调用`cond.Signal()`来唤醒等待的goroutine。注意,在使用条件变量时,必须始终在互斥锁的保护下进行操作,以确保线程安全。