【问题标题】:Resolving duplicate mutex lock in Go解决 Go 中的重复互斥锁
【发布时间】:2015-10-22 16:21:01
【问题描述】:

我在一个 Go 程序中有一堆函数,它们作用于一个使用互斥体来管理对其函数的并发访问的结构。

其中一些对特定数据进行操作的函数需要锁,因此使用 mutex.Lock() 来获取管理对该数据的访问的互斥锁。今天我遇到了两个锁定方法相互调用的问题。一旦第二次调用 mutex.Lock() 它就会阻塞 - 当然。

我面临的问题与这段代码非常相似:http://play.golang.org/p/rPARZsordI

Go 中是否有关于如何解决此问题的最佳实践?据我所知,递归锁在 Go 中不可用。

【问题讨论】:

  • 拥有一个锁定、写入和解锁的方法,并让所有其他方法使用该方法。

标签: multithreading go mutex


【解决方案1】:

这似乎是您系统的设计缺陷。您应该考虑需要锁定和解锁的部分。例如。如果你做的是

func (t *Thing) A() { t.Lock(); defer t.Unlock(); t.foo(); t.B() }
func (t *Thing) B() { t.Lock(); defer t.Unlock(); t.bar() }

那么你应该做的是

func (t *Thing) A() { t.Lock(); defer t.Unlock(); t.foo(); t.b() }
func (t *Thing) B() { t.Lock(); defer t.Unlock(); t.b() }
func (t *Thing) b() { t.bar() }

【讨论】:

  • 谢谢。我只是重构了代码以更接近实际的数据访问,这解决了这个问题。似乎我在代码中太深了,看不到那个明显的错误。
  • 我宁愿让b() 进行锁定。从您的示例看来,t.bar() 是同时敏感的资源,而不是 A()B()
  • 所以可以是t.foo()。这是关于可组合性的,您需要在一个“事务”中执行 t.foo()t.bar() 的情况。小写方法是未导出的,因此它们不应该只在包外部使用。
猜你喜欢
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 2022-07-31
  • 2021-06-21
  • 1970-01-01
  • 2015-09-26
  • 2021-12-23
  • 2010-11-22
相关资源
最近更新 更多