Golang Mutex 用于锁定特定的变量/映射(Map)

6
我对Golang中的互斥锁如何工作有些困惑,尽管我以前使用过它们。
以下是我的问题:
1. 互斥锁确切地锁定了什么?(如何)只锁定特定变量? 2. 我应该使用通道而不是互斥锁吗? 3. 互斥锁和locker之间有区别吗?
我正在使用Golang开发高并发网站,并需要在不同时间管理每个人的钱包,我试图避免程序中的任何竞争。例如,如果我的程序想要为用户添加500积分,它将读取用户的当前余额(从firebase)并添加500,然后更新该值。但是,如果由于某种原因它执行了两次,则可能会对用户的钱包造成错误的更改。
3个回答

4

什么是Mutex?

一般来说,“互斥”构造(或mutex)有助于并发控制。定义mutex的语言允许程序员定义一个临界代码段,只能由单个执行线程进入。 这里是Go中使用mutex的简单示例这里是更详细的mutex使用示例

Mutex还是Channel?

在决定是否在您的Go应用程序中使用基于mutex还是channel的设计时,选择并不总是非常明显。这篇来自Go github库的维基文章给出了以下建议:

Channel:传递数据所有权,分配工作单元,异步通信结果

Mutex:缓存,状态

Mutex还是sync.Locker?

正如@JimB指出的那样,Go中的sync.Mutex类型满足sync.Locker接口类型。注意,sync.MutexLock()Unlock()方法吗?因此,在Go中,sync.Mutexsync.Locker

如需了解更多关于Go接口的帮助,请查看这篇精彩的博客文章


1
-1 抱歉,丹,该OP问的是什么被锁定了,但这并没有得到回答。虽然有更多详细信息的链接,但是链接会失效。SO答案应该包括所有相关详细信息。 - Luke Puplett
“问具体锁住了什么”……嗯,我想我已经回答过了,“互斥锁允许程序员定义一段关键代码区域,只能由单个执行线程进入”。 - Dan Esparza
1
我认为混淆的原因是因为在其他语言中,“锁定”语句会应用于对象引用。更混乱的情况是,Win32中的Mutex是系统级别的,这是一种应用程序知道另一个应用程序正在运行的方式,因此“被锁定的东西”只是一个标识符,例如您的应用程序名称。 - Luke Puplett

2
  1. Mutex 只锁定自身。在你的代码中,你需要决定这个锁表示什么。
  2. 使用通道在 goroutine 之间进行同步和通信。使用 mutex 在单个逻辑资源周围提供“互斥锁”。
  3. mutex 满足 sync.Locker 接口。需要 sync.Locker 的内容可以交替使用 sync.Mutexsync.RWMutex

同步原语与防止重复事务的概念无关。正确使用同步只会防止程序中的数据竞争。


我在godoc上读到了一个mutex满足sync.Locker接口,但是并不真正理解它的含义。我正在寻找解释。此外,我如何使用mutex仅锁定特定变量?(你可以决定这代表什么?) - Ari Seyhun
1
@Acidic: "接口" 是 Go 语言中需要理解以使用该语言的主要概念。也许可以从官方文档开始,例如 Effective Go 中的相应部分或者 Tour of Go。在你的代码中,互斥锁和其锁定的内容之间没有任何关系,除非你如何使用它。 - JimB

0

如果状态不在内存中,你真的不需要同步锁。但假设所有用户的钱包都在一个Map中,那么你就需要一把锁,因为并发写操作会导致竞态条件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接