go-mutex锁
Go语言里的Mutex和RwMutex
共享锁(S锁)又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S 锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。(多读/单写)
排他锁(X锁)又称写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。(单读/单写)
go里的mutex(普通锁):全局互斥锁特性(不支持同时读)----读写操作一样待遇 (类似于:只能加X锁,读写都是X锁)
sync.RWMutex:读写锁,支持单写多读特性。----读写操作不同待遇 (类似于:分两种Lock排他锁,RLock共享锁)
意思是:RWMutex是完全可以实现mutex的功能的,而RWMtex可以实现同时读。
- func (m *Mutex) Lock()
Lock⽅法锁住m,如果m已经加锁,则阻塞直到m解锁。 - func (m *Mutex) Unlock()
Unlock⽅法解锁m,如果m未加锁会导致运⾏时错误。锁和线程无关,可以由不同的线程加锁和解锁。
1.mutex无法实现分布式,多个请求怎么共享一个公共变量?
2.除非分布式请求,共享 sync.RWMutex 变量
Mutex使用
package main
import (
"fmt"
"sync"
"time"
)
// 共享变量
var (
m sync.Mutex
v1 int
)
// 修改共享变量
// 在Lock()和Unlock()之间的代码部分是临界区
func change(i int, m *sync.Mutex) {
m.Lock()
time.Sleep(time.Second)
v1 = v1 + 1
fmt.Printf("Write %dth time, v1:%d.\n", i, v1)
m.Unlock()
}
func read(i int, m *sync.Mutex) {
m.Lock()
fmt.Printf("Read %dth time, v1:%d.\n", i, v1)
m.Unlock()
}
func main() {
var numGR = 10
var wg sync.WaitGroup
for i := 0; i < numGR; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
change(i, &m)
read(i, &m) //读和写都不会同时进行
}(i)
}
wg.Wait()
}
RWMutex使用
package main
import (
"fmt"
"sync"
"time"
)
// 共享变量
var (
m sync.RWMutex
v1 int
)
// 修改共享变量
// 在Lock()和Unlock()之间的代码部分是临界区
func change(i int, m *sync.RWMutex) {
m.Lock()
time.Sleep(time.Second)
v1 = v1 + 1
fmt.Printf("Write %dth time, v1:%d.\n", i, v1)
m.Unlock()
}
func read(i int, m *sync.RWMutex) {
m.RLock()
time.Sleep(time.Second)
v1 = v1 + 1
fmt.Printf("Read %dth time, v1:%d.\n", i, v1)
m.RUnlock()
}
func main() {
var numGR = 10000
var wg sync.WaitGroup
for i := 0; i < numGR; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
// change(i, &m)
read(i, &m)
}(i)
}
wg.Wait()
}
提示:并发量不高的情况下,如100,发现用共享锁获得的数据是完全没重复的,像是互斥锁的效果。但是只是并发量不高,10000并发量,共享锁的效果就提现出来了。猜测:for循环间隔时间大于自增时间了??盲猜

浙公网安备 33010602011771号