【问题标题】:Wait on a mutex without acquiring it [closed]等待互斥体而不获取它[关闭]
【发布时间】:2021-04-01 12:27:07
【问题描述】:

我一直在编写一个小型微服务,以便熟悉 Go 及其并发机制。

在我的程序中,我有一个具有状态的结构,我想同步该状态,以便多个 goroutine 能够读取它,但不能在另一个 goroutine 更新该状态时读取它。

最初我认为 RWMutax 是我所需要的,但根据文档,只有一个 goroutine 可以在任何给定的时刻获取读锁。我走这条线:

"如果一个 goroutine 持有一个 RWMutex 用于读取并且另一个 goroutine 可能会调用 Lock,任何 goroutine 都不应该期望能够获得 读锁,直到初始读锁被释放。”

有什么方法可以等待互斥体而不获取锁?

类似的东西:

type stateful struct {
    state        int
    stateMutex   sync.Mutex
    beingUpdated bool
}

type Stateful interface {
    GetState() int
    SetState(st int)
}

func createStateful (sa string) stateful {
    return server{state: 0, stateMutex: sync.Mutex{}, beingUpdated: false}
}

func (s *stateful) SetState(st int) {
    s.stateMutex.Lock()
    s.beingUpdated = true
    s.state = st
    s.beingUpdated = false
    s.stateMutex.Unlock()
}

func (s *stateful) GetState() bool {
    if s.beingUpdated {
        // wait for s.stateMutex to be unlocked
    }

    return s.state
}

【问题讨论】:

  • "只有一个 goroutine 可以在任何给定时刻获得读锁" 为什么你认为 RWMutex 是这样工作的?如果这是真的,那么 RW 互斥锁的整个想法就会被取消。
  • 来自文档:“如果一个 goroutine 持有一个 RWMutex 用于读取并且另一个 goroutine 可能调用 Lock,那么在初始读取锁被释放之前,任何 goroutine 都不应该期望能够获取读取锁。”我用这条线来理解这个
  • 它读作“另一个 goroutine 可能调用 Lock”而不是 Rlock。当然,在没有任何其他阅读器的情况下,只能提供一个写入锁。

标签: go concurrency mutex


【解决方案1】:

您可能误读了sync.RWMutex docs

...锁可以由任意数量的读者或单个 作家。

所以你的代码简化如下:

type stateful struct {
    l     sync.RWMutex // style: place lock above ...
    state int        //        ... the field it protects
}

func (s *stateful) SetState(st int) {
    s.l.Lock()
    defer s.l.Unlock()

    s.state = st
}

func (s *stateful) GetState() int {
    s.l.RLock()
    defer s.l.RUnlock()

    return s.state
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-07
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 2012-12-27
    • 1970-01-01
    • 2012-06-14
    相关资源
    最近更新 更多