Go语言中同步锁有什么特点?作用是什么?
Go语言中同步锁有什么特点?作用是什么?
Go语言中同步锁 ,当一个 Goroutine(协程)获得了 Mutex 后,其他Goroutine(协程)就只能乖 乖的等待,除非该 Goroutine 释放了该 Mutex。RWMutex 在读锁占用的情况下,会阻止写,但不阻止读 RWMutex。 在写锁占用情况下,会阻止任何其他 Goroutine(无论读和写)进来,整个锁相当于由该 Goroutine 独占同步锁的作用是保证资源在使用时的独有性,不会因为并发而导致数据错乱, 保证系统的稳定性。
1 回复
在Go语言中,同步锁主要用于控制对共享资源的并发访问,以确保在并发环境下数据的完整性和一致性。Go标准库提供了多种同步机制,其中sync
包下的Mutex
(互斥锁)是最常用的同步锁之一。以下是Go语言中同步锁(以Mutex
为例)的特点和作用,以及一个简单示例。
特点
- 互斥性:同一时间只允许一个goroutine持有锁,其他goroutine必须等待锁被释放。
- 可重入性:Go的
Mutex
是不可重入的。如果一个goroutine已经持有了锁,它再次尝试加锁会导致死锁。 - 自动解锁:
Mutex
提供了Lock()
和Unlock()
方法,用于上锁和解锁。为了避免忘记解锁导致的死锁,Go 1.3及以后版本推荐使用defer Mutex.Unlock()
来确保锁在函数返回前被释放。 - 尝试锁定:
Mutex
还提供了TryLock()
的变种(通过TryLock()
或Lock()
配合channel模拟),允许goroutine尝试获取锁而不阻塞,如果锁已被其他goroutine持有,则立即返回而不等待。
作用
- 保护共享资源:防止多个goroutine同时访问和修改共享资源,导致数据竞争和不一致。
- 实现同步:确保多个goroutine按照预定的顺序访问资源或执行代码段。
示例代码
package main
import (
"fmt"
"sync"
"time"
)
var (
// 假设这是一个需要保护的共享资源
counter int
// 使用互斥锁来保护counter
lock sync.Mutex
)
func increment(wg *sync.WaitGroup) {
defer wg.Done()
// 上锁
lock.Lock()
// 模拟耗时操作
time.Sleep(time.Millisecond * 100)
counter++
fmt.Println("Counter:", counter)
// 解锁
lock.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
}
在这个示例中,counter
是一个被多个goroutine共享的整型变量,使用sync.Mutex
来保护它。每个goroutine在修改counter
之前都会先尝试获取锁,修改完毕后释放锁,从而确保counter
的每次修改都是原子的,避免了数据竞争。