RWMutex(读写锁)
通过对互斥锁的学习,我们已经了解了锁的概念及用途。主要用于处理并发中的临界资源问题。
RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能。
RWMutext是读/写互斥锁。锁可以由任意数量的读取器或单个编写器持有。RWMutex的零值是未锁定的mutex。
当有一个goroutine获得写锁定,其他无论是读锁定还是写锁定都将阻塞知道写解锁;
当有一个goroutine获得读锁定,其他读锁定仍然可以继续;当有一个或任意多个读锁定,写锁定将等待所有读锁定解锁之后才能进行写锁定。因此可以总结为:
- 同时只能有一个goroutine能够获得写锁定。
- 同时可以有多个goroutine能够获得读锁定。
- 同时只能存在写锁定或者读锁定(读写互斥)
RWMutex的方法
方法名 | 功能 |
---|---|
(*RWMutext)Lock() | 写锁定 |
(*RWMutex)Unlock() | 写解锁 |
(*RWMutex)RLock() | 读锁定 |
(*RWMutex)RUnlock() | 读解锁 |
下面代码实现了一个读锁定的实例:
package main
import (
"fmt"
"sync"
"time"
)
var rwMutex *sync.RWMutex
var wg *sync.WaitGroup
func main(){
rwMutex = new(sync.RWMutex)
wg = new (sync.WaitGroup)
wg.Add(2)
go readData(1)
go readData(2)
wg.Wait()
fmt.Println("main over..")
}
func readData(i int){
defer wg.Done()
fmt.Println(i,"开始读:read start..")
rwMutex.RLock()
fmt.Println(i,"正在读取数据:reading..")
time.Sleep(1*time.Second)
rwMutex.RUnlock()
fmt.Println(i,"读结束:read over..")
}
控制台输出
2 开始读:read start..
2 正在读取数据:reading..
1 开始读:read start..
1 正在读取数据:reading..
2 读结束:read over..
1 读结束:read over..
或者
2 开始读:read start..
1 开始读:read start..
1 正在读取数据:reading..
2 正在读取数据:reading..
1 读结束:read over..
2 读结束:read over..
main over..
下面代码实现了读写锁的应用示例:
package main
import (
"fmt"
"sync"
"time"
)
var rwMutex *sync.RWMutex
var wg *sync.WaitGroup
func main(){
rwMutex = new(sync.RWMutex)
wg = new (sync.WaitGroup)
wg.Add(3)
go readData(1)
go writeData(2)
go readData(3)
wg.Wait()
fmt.Println("main over..")
}
func writeData(i int){
defer wg.Done()
fmt.Println(i,"开始写:write start..")
rwMutex.Lock()
fmt.Println(i,"正在写:writing..")
time.Sleep(3*time.Second)
rwMutex.Unlock()
fmt.Println(i,"写结束:write over..")
}
func readData(i int){
defer wg.Done()
fmt.Println(i,"开始读:read start..")
rwMutex.RLock()
fmt.Println(i,"正在读取数据:reading..")
time.Sleep(3*time.Second)
rwMutex.RUnlock()
fmt.Println(i,"读结束:read over..")
}
控制台输出,关键的互斥点在”正在读取数据和正在写上“,读者可以自行改变代码多次运行体会:
3 开始读:read start..
1 开始读:read start..
1 正在读取数据:reading..
3 正在读取数据:reading..
2 开始写:write start..
3 读结束:read over..
2 正在写:writing..
1 读结束:read over..
2 写结束:write over..
main over..
或者…:
3 开始读:read start..
3 正在读取数据:reading..
1 开始读:read start..
1 正在读取数据:reading..
2 开始写:write start..
3 读结束:read over..
2 正在写:writing..
1 读结束:read over..
2 写结束:write over..