From 90e8bf93ca35a43aac232ca291babc6de31dbe42 Mon Sep 17 00:00:00 2001 From: yanzuoguang Date: Sun, 2 Nov 2025 15:22:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(main):=20=E6=B7=BB=E5=8A=A0=20main3=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9E=E7=8E=B0=E8=AF=BB=E5=86=99=E9=94=81?= =?UTF-8?q?=E4=B8=8E=E6=9D=A1=E4=BB=B6=E5=8F=98=E9=87=8F=E5=8D=8F=E5=90=8C?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 generateSquares 函数用于生成平方数并广播条件变量- 新增 readSquares 函数等待数据准备完成后进行读取操作 - 在 main3 中初始化并发读取和数据生成的同步流程 - 使用 sync.RWMutex 和 sync.Cond 实现更复杂的并发控制逻辑 - 增加对 map 数据结构的安全访问机制 - main 函数中调用新增的 main3 方法以执行相关功能 --- 30-coordination/coordination/main.go | 58 +++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/30-coordination/coordination/main.go b/30-coordination/coordination/main.go index 12e0629..006813d 100644 --- a/30-coordination/coordination/main.go +++ b/30-coordination/coordination/main.go @@ -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)) }