文章目录
读写锁是针对于读写操作的互斥锁。
基本遵循两大原则:
1、可以随便读。多个gorouting同时读。
2、写的时候,啥都不能干。不能读,也不能写。
解释:
在32位的操作系统中,针对int64类型值的读操作和写操作不可能只由一个CPU指令完成。如果一个写的操作刚执行完了第一个指令,时间片换给另一个读的协程,这就会读到一个错误的数据。
RWMutex提供四个方法:
1 2 3 4 5 6 7
| func (*RWMutex) Lock
func (*RWMutex) Unlock
func (*RWMutex) RLock
func (*RWMutex) RUnlock
|
代码实例:
1、可以随便读:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| package main
import (
"sync"
"time"
)
var m *sync.RWMutex
func main() {
m = new(sync.RWMutex)
go read(1)
go read(2)
time.Sleep(2 * time.Second)
}
func read(i int) {
println(i, "read start")
m.RLock()
println(i, "reading")
time.Sleep(1 * time.Second)
m.RUnlock()
println(i, "read end")
}
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11
| 1 read start
1 reading
2 read start
2 reading
1 read end
2 read end
|
可以看到1读还没结束(倒数第二行)的时候,2已经在读(倒数第三行)了。
2、写的时候啥也不能干:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| package main
import (
"sync"
"time"
)
var m *sync.RWMutex
func main() {
m = new(sync.RWMutex)
go write(1)
go read(2)
go write(3)
time.Sleep(4 * time.Second)
}
func read(i int) {
println(i, "read start")
m.RLock()
println(i, "reading")
time.Sleep(1 * time.Second)
m.RUnlock()
println(i, "read end")
}
func write(i int) {
println(i, "write start")
m.Lock()
println(i, "writing")
time.Sleep(1 * time.Second)
m.Unlock()
println(i, "write end")
}
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 1 write start
1 writing
2 read start
3 write start
1 write end
2 reading
2 read end
3 writing
3 write end
|
可以看到:
1、1 write end结束之后,2才能reading
2、2 read end结束之后,3 才能writing