发布时间:2024-11-22 00:29:39
在并发编程中,我们经常面临需要对共享资源进行访问控制的情况。Golang 提供了多种锁机制来实现线程安全的并发控制,本文将介绍其中的几种常用方式。
Mutex 锁是 Golang 中最基础的一种锁机制。它通过互斥的方式来保护共享资源。获取到 Mutex 锁的 goroutine 可以访问共享资源,其他尝试获取该锁的 goroutine 会被阻塞。
下面是 Mutex 锁的一个简单示例:
var (
mutex = sync.Mutex{}
count = 0
)
func increment() {
mutex.Lock()
defer mutex.Unlock()
count++
}
在上述代码中,使用 `sync.Mutex` 定义了一个全局的 Mutex 对象 `mutex`,以及需要被保护的共享变量 `count`。在 `increment` 函数中,我们首先调用 `mutex.Lock` 获取锁,然后在函数结束时使用 `defer mutex.Unlock` 释放锁。
RWMutex 锁是 Mutex 锁的一种改进,它在保证线程安全的同时提供了更好的并发性能。RWMutex 锁允许多个 goroutine 同时获得读锁,但只允许一个 goroutine 获取写锁。
使用 RWMutex 锁的示例代码:
var (
rwMutex = sync.RWMutex{}
count = 0
)
func readCount() int {
rwMutex.RLock()
defer rwMutex.RUnlock()
return count
}
func writeCount(value int) {
rwMutex.Lock()
defer rwMutex.Unlock()
count = value
}
在上述代码中,我们使用 `sync.RWMutex` 定义了一个全局的 RWMutex 对象 `rwMutex`,以及需要被保护的共享变量 `count`。`readCount` 函数获取读锁并返回 count 的值,`writeCount` 函数获取写锁并更新 count 的值。
除了使用锁机制来保护共享资源外,Golang 还提供了 WaitGroup 机制来进行并发控制。WaitGroup 用于等待一组 goroutine 的完成。当某个 goroutine 完成时,它会调用 `Done` 方法来通知 WaitGroup,而等待该组 goroutine 完成的 goroutine 可以调用 `Wait` 方法来阻塞等待。
下面是一个使用 WaitGroup 的示例代码:
var wg sync.WaitGroup
func worker(id int) {
defer wg.Done()
time.Sleep(1 * time.Second)
fmt.Printf("Worker %d 完成\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i)
}
wg.Wait()
fmt.Println("所有 Worker 完成")
}
在上述代码中,我们创建了一个 WaitGroup 对象 `wg`,然后使用 `wg.Add` 方法来设置需要等待的 goroutine 数量。每个 worker 函数的最后都会调用 `wg.Done` 方法来通知 WaitGroup,主函数最后调用 `wg.Wait` 方法来阻塞等待所有的 goroutine 完成。
Golang 提供了多种锁机制来实现并发控制。Mutex 锁适用于互斥访问共享资源的场景,RWMutex 锁提供了更好的并发性能,而 WaitGroup 则用于等待一组 goroutine 的完成。
根据不同的场景需求,选择合适的锁机制可以提高程序的并发性能,并保证共享资源的正确访问。