继GO语言锁机制(1)后,我们继续来探讨GO语言的锁机制
sync.RWMutex (读写锁,R代表度,W代表写)
读写锁是读/写互斥锁的简称。在Go语言中,读写锁由sync.RWMutex类型的值代表。与sync.Mutex类型一样,这个类型也是开箱即用的。
顾名思义,读写锁是把对共享资源的“读操作”和“写操作”区别对待了。它可以对这两种操作施加不同程度的保护。换句话说,相比于互斥锁,读写锁可以实现更加细腻的访问控制。
例子
demo2
package sync_26_28
import (
"github.com/wonderivan/logger"
"sync"
"time"
)
var book = []string{"床前明月光", "疑是地上霜", "举头忘明月", "低头思故乡"}
//var blackboard = &atomic.Value{}
var blackboard string
var page int
var rwmutext = sync.RWMutex{}
type Student struct {
Name string
Rtext string
}
type Teacher struct {
Name string
Wtext string
}
func (s *Student) read() {
logger.Info(s.Name + " request read ...")
rwmutext.RLock()
defer rwmutext.RUnlock()
logger.Info(s.Name + " start read ")
//s.Rtext = blackboard.Load().(string)
s.Rtext = blackboard
time.Sleep(time.Second)
logger.Info(s.Name + " end read " + s.Rtext)
}
func (t *Teacher) write(index int) {
logger.Info(t.Name + " request write ...")
rwmutext.Lock()
if index == page {
logger.Info(t.Name + " start write ...")
t.Wtext = book[page]
time.Sleep(time.Second * 3) // 写这句花了 3秒钟
//blackboard.Store(t.Wtext)
blackboard = t.Wtext
page++
//logger.Info(t.Name+" finish. blackboard: ", blackboard.Load())
logger.Info(t.Name+" finish. blackboard: ", blackboard)
rwmutext.Unlock()
time.Sleep(time.Second * 3) // 写完休息一下给学生们读
} else {
logger.Info(t.Name + " end 放弃 ...")
rwmutext.Unlock()
}
}
func RwTest01() {
sa := &Student{Name: "S-a"}
sb := &Student{Name: "S-b"}
sc := &Student{Name: "S-c"}
ta := &Teacher{Name: "T-a"}
tb := &Teacher{Name: "T-b"}
go startWrite(ta)
go startWrite(tb)
time.Sleep(time.Second * 1) // 粗鲁的控制,让老师写开始写
go startRead(sa)
go startRead(sb)
go startRead(sc)
}
func startRead(s *Student) {
for i := 0; i < 1000; i++ {
s.read()
}
}
func startWrite(t *Teacher) {
for i := 0; i < 4; i++ {
t.write(i)
}
}
RWMutex的四种操作方法
RLock() //读锁定
RUnlock() //读解锁
Lock() //写锁定
Unlock() //写解锁
RWMutex的使用主要事项
这个例子意思就是两个老师在看一本只有四页的书,把书里的内容写到黑板上,有三个学生一直在读黑板上的内容。
1.a老师在写的时候,b老师写不了
写锁的时候要等待写锁的结束
2.老师们在写新内容的时候,要确保学生们都看完了黑板上内容
写锁的时候要等待读锁的结束
3.老师们写的是时候整个身子挡住了黑板,学生们得到老师写完了,离开黑板才能看间写的内容
读锁要等待写锁的结束
4.黑板就在哪里学生们都可以看到
读锁无需等待读锁借宿
值得一提的是 读锁虽然不需要等待读锁的结束,不过确是有最大读锁限制的。
2019-03-27 12:58:33 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-a request write ...
2019-03-27 12:58:33 [INFO] [untitled/sync_26_28/demo_rwmutex.go:43] T-a start write ...
2019-03-27 12:58:33 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-b request write ...
2019-03-27 12:58:34 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:34 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:34 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:36 [INFO] [untitled/sync_26_28/demo_rwmutex.go:50] T-a finish. blackboard: 床前明月光
2019-03-27 12:58:36 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:36 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:36 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-c end read 床前明月光
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 床前明月光
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 床前明月光
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:54] T-b end 放弃 ...
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-b request write ...
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:37 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:38 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-c end read 床前明月光
2019-03-27 12:58:38 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:38 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 床前明月光
2019-03-27 12:58:38 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:38 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 床前明月光
2019-03-27 12:58:38 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:38 [INFO] [untitled/sync_26_28/demo_rwmutex.go:43] T-b start write ...
2019-03-27 12:58:39 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-a request write ...
2019-03-27 12:58:41 [INFO] [untitled/sync_26_28/demo_rwmutex.go:50] T-b finish. blackboard: 疑是地上霜
2019-03-27 12:58:41 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:41 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:41 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 疑是地上霜
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-c end read 疑是地上霜
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 疑是地上霜
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:54] T-a end 放弃 ...
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-a request write ...
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:42 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:43 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 疑是地上霜
2019-03-27 12:58:43 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:43 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-c end read 疑是地上霜
2019-03-27 12:58:43 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:43 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 疑是地上霜
2019-03-27 12:58:43 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:43 [INFO] [untitled/sync_26_28/demo_rwmutex.go:43] T-a start write ...
2019-03-27 12:58:44 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-b request write ...
2019-03-27 12:58:46 [INFO] [untitled/sync_26_28/demo_rwmutex.go:50] T-a finish. blackboard: 举头忘明月
2019-03-27 12:58:46 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:46 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:46 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-c end read 举头忘明月
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 举头忘明月
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 举头忘明月
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:54] T-b end 放弃 ...
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-b request write ...
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:47 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:48 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-c end read 举头忘明月
2019-03-27 12:58:48 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 举头忘明月
2019-03-27 12:58:48 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:48 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 举头忘明月
2019-03-27 12:58:48 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:48 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:48 [INFO] [untitled/sync_26_28/demo_rwmutex.go:43] T-b start write ...
2019-03-27 12:58:49 [INFO] [untitled/sync_26_28/demo_rwmutex.go:39] T-a request write ...
2019-03-27 12:58:51 [INFO] [untitled/sync_26_28/demo_rwmutex.go:50] T-b finish. blackboard: 低头思故乡
2019-03-27 12:58:51 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:51 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:51 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-c end read 低头思故乡
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-c request read ...
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 低头思故乡
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-a request read ...
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 低头思故乡
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:28] S-b request read ...
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:54] T-a end 放弃 ...
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-b start read
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-c start read
2019-03-27 12:58:52 [INFO] [untitled/sync_26_28/demo_rwmutex.go:31] S-a start read
2019-03-27 12:58:53 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-b end read 低头思故乡
2019-03-27 12:58:53 [INFO] [untitled/sync_26_28/demo_rwmutex.go:35] S-a end read 低头思故乡