文章目录

读写锁是针对于读写操作的互斥锁。

基本遵循两大原则:

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
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

文章目录