互斥锁和读写互斥锁
## 互斥锁 互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥锁。 定义一个锁: ```go var lock sync.Mutex ``` 加锁: ```go lock.Lock() ``` 解锁: ```go lock.Unlock() ``` ## 完整示例 ```go package main import ( "fmt" "sync" ) func main() { var lock sync.Mutex var wg sync.WaitGroup x := 0 // 开100个goroutine for i := 0; i < 100; i++ { // 计数 wg.Add(1) go func() { // 锁了之后其它goroutine不能对x进行操作 lock.Lock() for j := 0; j < 100; j++ { x += 1 } // 解锁 lock.Unlock() // 执行完毕 wg.Done() }() } // 等待所有goroutine执行完毕 wg.Wait() // 输出x(10000) fmt.Println(x) } ``` ## 读写互斥锁 互斥锁是完全互斥的,但是有很多实际的场景下是读多写少的,当并发的去读取一个资源不涉及资源修改的时候是没有必要加锁的,这种场景下使用读写锁是更好的一种选择。读写锁在Go语言中使用sync包中的RWMutex类型。 读写锁分为两种:读锁和写锁。当一个goroutine获取读锁之后,其他的goroutine如果是获取读锁会继续获得锁,如果是获取写锁就会等待;当一个goroutine获取写锁之后,其他的goroutine无论是获取读锁还是写锁都会等待。 定义一个读写锁: ```go var rwlock sync.RWMutex ``` 加写锁: ```go rwlock.Lock() ``` 解写锁: ```go rwlock.Unlock() ``` 加读锁: ```go rwlock.RLock() ``` 解读锁: ```go rwlock.RUnlock() ``` ## 完整示例 ```go package main import ( "fmt" "sync" ) func main() { var rwlock sync.RWMutex var wg sync.WaitGroup x := 0 wg.Add(1) // 读x go func() { for a := 0; a < 100; a++ { // 读锁 rwlock.RLock() fmt.Println(x) // 解读锁 rwlock.RUnlock() } wg.Done() }() // 开100个goroutine写入x for i := 0; i < 100; i++ { // 计数 wg.Add(1) go func() { // 写锁 rwlock.Lock() for j := 0; j < 100; j++ { x += 1 } // 解写锁 rwlock.Unlock() // 执行完毕 wg.Done() }() } // 等待所有goroutine执行完毕 wg.Wait() } ``` 运行后可发现每次读操作输出的结果,都相差100,因为写锁在解开前不能进行读操作,因此只有等x加上100后才能读,而读锁在解开前不能进行写操作,因此每次读的时候x不能修改。
创建时间:2023-09-13
|
最后修改:2023-12-27
|
©允许规范转载
酷酷番茄
首页
文章
友链