关于golang中RWMutex的疑问

题目描述

关于golang中RWMutex的疑问

题目来源及自己的思路

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

package main

import (
    "fmt"
    "sync"
    "time"
)

type Stu struct {
    Name string
    mu *sync.RWMutex
}

func read1(stu *Stu)  {
    stu.mu.RLock()
    stu.Name = "aa"
    fmt.Println("read1 start")
    time.Sleep(time.Second * 5)
    stu.mu.RUnlock()
    fmt.Println("read1 end")
}

func read2(stu *Stu)  {
    stu.mu.RLock()
    fmt.Println("read2 start")
    time.Sleep(time.Second * 5)
    stu.mu.RUnlock()
    fmt.Println("read2 end")
}

func write1(stu *Stu)  {
    stu.mu.Lock()
    fmt.Println("write1 start")
    time.Sleep(time.Second * 5)
    stu.mu.Unlock()
    fmt.Println("write1 end")
}

func main() {
    stu := new(Stu)
    stu.mu = new(sync.RWMutex)
    go func() {
        read1(stu)
    }()
    go func() {
        read2(stu)
    }()
    go func() {
        write1(stu)
    }()
    time.Sleep(time.Second * 40)

}

你期待的结果是什么?实际看到的错误信息又是什么?

返回结果:
read1 start
read1 end
write1 start
write1 end
read2 start
read2 end

疑问:
为啥不是
read2 start
read1 start
read2 end
read1 end
write1 start
write1 end

这里我认为加了读锁的read1和read2应该并发,但是事实情况是偶尔并发,偶尔只有read1执行完才执行read2

阅读 2.1k
2 个回答

golang中RWLock的内部排队机制问题,如果要加写锁失败时进入排队队列,会阻止后面的读锁。

你的理解没有问题,只是你的写法有问题

fmt.Println("read1 end") 
stu.mu.RUnlock()

我的意思是所有print都应该在lock里面
unlock之后其他协程已经可以执行了,你的print毫无意义

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题