当前位置: 首页 > 面试题库 >

什么时候将互斥锁嵌入到struct中?

葛意远
2023-03-14
问题内容

注意:我发现标题中的“嵌入”一词是错误的选择,但我会保留。

我看到很多代码是这样的:

type A struct {
    mu sync.Mutex
    ...
}

并像这样使用它:

a := &A{}

a.mu.Lock()
defer a.mu.Unlock()

a.Something()

它比本地互斥锁或全局互斥锁更好吗?

a := &A{}

var mu sync.Mutex
mu.Lock()
defer mu.Unlock()

a.Something()

我应该什么时候使用前一个或更晚的版本?


问题答案:

保持互斥锁接近要保护的数据是一种好习惯。如果互斥锁应该保护对结构值字段的并发访问,则将互斥锁添加为该结构的字段非常方便,因此其目的显而易见。

如果您的应用程序中只有一个“实例” A,那么也可以将互斥锁也设为全局变量

如果您的应用程序要创建的多个值A,则需要保护所有这些值以防止并发访问(但只能单独访问,可以同时访问多个值),那么显然,全局互斥锁是一个不好的选择,它将限制并发访问。A在任何时间点的单个值。

将互斥量作为字段添加到结构中,您 自然 会为每个不同的结构值拥有一个单独的互斥体,负责保护包含该结构值(或其字段)的单个互斥量。

尽管在您的示例中未添加互斥锁,但它是一个常规的命名字段。在嵌入式领域声明省略字段名。

它的知名度和使用程度较小,但也很方便,您可以“真正地”将互斥体嵌入结构中,并且可以进行调用Lock()Unlock()就好像它们将成为结构本身的一部分一样。看起来像这样:

var hits struct {
    sync.Mutex
    n int
}

hits.Lock()
hits.n++
hits.Unlock()

(此示例摘自您(可能)对Go不了解的10件事,幻灯片#3。)



 类似资料:
  • Go语言包中的 sync 包提供了两种锁类型:sync.Mutex 和 sync.RWMutex。 Mutex 是最简单的一种锁类型,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex。 RWMutex 相对友好些,是经典的单写多读模型。在读锁占用的情况下,会阻止写,但不阻止读,也就是多个 gor

  • Introduction This is the fourth part of the chapter which describes synchronization primitives in the Linux kernel and in the previous parts we finished to consider different types spinlocks and semap

  • 本文向大家介绍互斥锁死锁,包括了互斥锁死锁的使用技巧和注意事项,需要的朋友参考一下 死锁可以在使用互斥锁的多线程Pthread程序中发生。让我们看看它如何发生。未锁定的互斥锁由pthread_mutex_init()函数初始化。 使用pthread_mutex_lock()和pthread_mutex_unlock()获取并释放互斥锁。如果线程尝试获取锁定的互斥锁,则对pthread_mutex_

  • 9.2. sync.Mutex互斥锁 在8.6节中,我们使用了一个buffered channel作为一个计数信号量,来保证最多只有20个goroutine会同时执行HTTP请求。同理,我们可以用一个容量只有1的channel来保证最多只有一个goroutine在同一时刻访问一个共享变量。一个只能为1和0的信号量叫做二元信号量(binary semaphore)。 gopl.io/ch9/bank

  • 问题内容: 是多线程/进程编程的新手。所以这是我需要澄清的。 处理代码 使用上述伪代码,如果互斥锁未解锁,进程B是否可以访问? 如何从进程B正确访问sharedResource? 有没有清晰的可视化图表说明互斥体,线程和进程之间的关系? 问题答案: 您需要做的是调用pthread_mutex_lock来保护互斥锁,如下所示: 一旦执行此操作,在您在该线程中进行调用之前,不会再进行任何其他调用。因此

  • 问题内容: 帮助客户解决他们遇到的问题。我更多地是sysadmin / DBA的人,所以我在努力帮助他们。他们说这是内核/环境中的错误,在我坚持要在他们的代码中或寻求供应商对OS的支持之前,我试图证明或证明这一点。 发生在Red Hat和Oracle Enterprise Linux 5.7(和5.8)上,应用程序用C ++编写 他们遇到的问题是主线程启动一个单独的线程来执行可能长时间运行的TCP