feat(main): 添加 main3 函数实现读写锁与条件变量协同工作

- 新增 generateSquares 函数用于生成平方数并广播条件变量- 新增 readSquares 函数等待数据准备完成后进行读取操作
- 在 main3 中初始化并发读取和数据生成的同步流程
- 使用 sync.RWMutex 和 sync.Cond 实现更复杂的并发控制逻辑
- 增加对 map 数据结构的安全访问机制
- main 函数中调用新增的 main3 方法以执行相关功能
This commit is contained in:
2025-11-02 15:22:56 +08:00
parent fce9ed0d36
commit 90e8bf93ca

View File

@@ -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))
}