feat(main): 添加 main3 函数实现读写锁与条件变量协同工作
- 新增 generateSquares 函数用于生成平方数并广播条件变量- 新增 readSquares 函数等待数据准备完成后进行读取操作 - 在 main3 中初始化并发读取和数据生成的同步流程 - 使用 sync.RWMutex 和 sync.Cond 实现更复杂的并发控制逻辑 - 增加对 map 数据结构的安全访问机制 - main 函数中调用新增的 main3 方法以执行相关功能
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
func main() {
|
||||
main1()
|
||||
main2()
|
||||
main3()
|
||||
}
|
||||
|
||||
func doSum(count int, val *int, waitGroup *sync.WaitGroup, mutex *sync.Mutex) {
|
||||
@@ -39,13 +40,16 @@ func main1() {
|
||||
func calculateSquares(index, max, iterations int, r *rand.Rand, waitGroup *sync.WaitGroup, rwMutex *sync.RWMutex, squares map[int]int) {
|
||||
for i := 0; i < iterations; i++ {
|
||||
val := r.Intn(max)
|
||||
// 读取锁
|
||||
rwMutex.RLock()
|
||||
square, ok := squares[val]
|
||||
rwMutex.RUnlock()
|
||||
if ok {
|
||||
Printfln("%v %v RLock Cached value: %v = %v ", index, i, val, square)
|
||||
} else {
|
||||
// 写锁,当没有读到时,开启写锁
|
||||
rwMutex.Lock()
|
||||
// 重新读取值,防止缓存被其他goroutine修改
|
||||
if square, ok := squares[val]; !ok {
|
||||
squares[val] = int(math.Pow(float64(val), 2))
|
||||
Printfln("%v %v Added value: %v = %v", index, i, val, squares[val])
|
||||
@@ -72,5 +76,57 @@ func main2() {
|
||||
}
|
||||
waitGroup.Wait()
|
||||
Printfln("Cached Value: %v", len(squares))
|
||||
|
||||
}
|
||||
|
||||
func generateSquares(max int, waitGroup *sync.WaitGroup, rwMutex *sync.RWMutex, readyCond *sync.Cond, squares map[int]int) {
|
||||
// 开启写锁
|
||||
rwMutex.Lock()
|
||||
// 重新读取值,防止缓存被其他goroutine修改
|
||||
Printfln("Generating data...")
|
||||
for i := 0; i < max; i++ {
|
||||
squares[i] = int(math.Pow(float64(i), 2))
|
||||
}
|
||||
// 关闭写锁
|
||||
rwMutex.Unlock()
|
||||
|
||||
// 读锁开始广播
|
||||
Printfln("Broadcasting condition")
|
||||
readyCond.Broadcast()
|
||||
waitGroup.Done()
|
||||
}
|
||||
|
||||
func readSquares(id, max, iterations int, r *rand.Rand, waitGroup *sync.WaitGroup, readyCond *sync.Cond, squares map[int]int) {
|
||||
readyCond.L.Lock()
|
||||
for len(squares) == 0 {
|
||||
readyCond.Wait()
|
||||
}
|
||||
for i := 0; i < iterations; i++ {
|
||||
key := r.Intn(max)
|
||||
Printfln("#%v,%v Read Index: %v = %v ", id, i, key, squares[key])
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
readyCond.L.Unlock()
|
||||
waitGroup.Done()
|
||||
}
|
||||
|
||||
func main3() {
|
||||
Printfln("\nmain3:")
|
||||
|
||||
var waitGroup = sync.WaitGroup{}
|
||||
var rwMutex = sync.RWMutex{}
|
||||
var readyCond = sync.NewCond(rwMutex.RLocker())
|
||||
var squares = map[int]int{}
|
||||
|
||||
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
numRoutines := 2
|
||||
for i := 0; i < numRoutines; i++ {
|
||||
waitGroup.Add(1)
|
||||
go readSquares(i, 10, 5, r, &waitGroup, readyCond, squares)
|
||||
}
|
||||
|
||||
waitGroup.Add(1)
|
||||
go generateSquares(10, &waitGroup, &rwMutex, readyCond, squares)
|
||||
|
||||
waitGroup.Wait()
|
||||
Printfln("Cached Value: %v", len(squares))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user