sync.RWMutex 功能的测试
RWMutex里共四个方法
func (rw *RWMutex) Lock() // 写锁
func (rw *RWMutex) Unlock() // 写解锁
func (rw *RWMutex) RLock() // 读锁
func (rw *RWMutex) RUnlock() // 读解锁
这里要着重理解下
- 读锁不互斥(可以多个一起读)
- 写锁互斥(只能有一个在写入)
- 有读不可写,有写不可读(读写不能同时进行)
我使用了两个方法验证加读写锁后的安全其中fun rwMutex(i int)
使用了RWMutex锁,开协程并发的累加到10000,同时开协程累减到10000,最终得到的值为0,证明加锁后是独写安全的fun rwWithoutMutex(i int)
没有使用了RWMutex锁,同上一方法先同时累加累减,得到结果不为预期值0,所以独写不安全
代码如下
type info struct {
sync.RWMutex
data int
}
func rwMutex(count int) {
c := make(chan struct{},count * 3)
l := info{data:0}
for i := 0; i < count; i++ {
go func() {
l.RLock()
d := l.data
fmt.Printf("我读取到了data,值为:%d\n",d)
l.RUnlock()
c <- struct{}{}
}()
}
for i := 0; i < count; i++ {
go func(i int) {
l.Lock()
l.data += i
fmt.Printf("我把data的值加了%d变成了%d\n",i,l.data)
l.Unlock()
c <- struct{}{}
}(i)
}
for i := 0; i < count; i++ {
go func(i int) {
l.Lock()
l.data -= i
fmt.Printf("我把data的值减了%d变成了%d\n",i,l.data)
l.Unlock()
c <- struct{}{}
}(i)
}
for i := 0; i < count * 3; i++ {
<-c
}
fmt.Printf("data的最终结果应该为0,实际结果为:%d",l.data)
}
func rwWithoutMutex(count int) {
c := make(chan struct{},count * 3)
l := 0
for i := 0; i < count; i++ {
go func() {
fmt.Printf("我读取到了data,值为:%d\n",l)
c <- struct{}{}
}()
}
for i := 0; i < count; i++ {
go func(i int) {
l += i
fmt.Printf("我把data的值加了%d变成了%d\n",i,l)
c <- struct{}{}
}(i)
}
for i := 0; i < count; i++ {
go func(i int) {
l -= i
fmt.Printf("我把data的值减了%d变成了%d\n",i,l)
c <- struct{}{}
}(i)
}
for i := 0; i < count * 3; i++ {
<-c
}
fmt.Printf("不安全读写时data的最终结果应该为0,实际结果为:%d",l)
}
调用 rwMutex(10000)
得到结果
... ...
我把data的值减了9869变成了88935
我把data的值减了9866变成了79069
我把data的值减了9867变成了69202
我把data的值减了9864变成了59338
我把data的值减了9929变成了49409
我把data的值减了9868变成了39541
我把data的值减了9928变成了29613
我把data的值减了9871变成了19742
我把data的值减了9870变成了9872
我把data的值减了9872变成了0
data的最终结果应该为0,实际结果为:0
调用 rwWithoutMutex(10000)
得到结果
... ...
我读取到了data,值为:0
我读取到了data,值为:0
我读取到了data,值为:0
我把data的值加了175变成了-30536
我把data的值加了1410变成了-30536
我读取到了data,值为:0
我把data的值加了811变成了-356884
我读取到了data,值为:0
我读取到了data,值为:0
不安全读写时data的最终结果应该为0,实际结果为:-30536
本作品采用《CC 协议》,转载必须注明作者和本文链接