【问题标题】:When to use mutexes?何时使用互斥锁?
【发布时间】:2014-03-22 22:10:01
【问题描述】:

我一直在玩 gtkmm 和多线程 GUI,偶然发现了 mutex 的概念。据我所知,它的目的是为单个线程锁定对变量的访问,以避免并发问题。我理解这似乎很自然,但是我仍然不明白应该如何以及何时应该使用 mutex。我已经看到了几种使用互斥锁仅被锁定以访问特定变量(例如like this tutorial)的情况。应该对哪种类型的变量/数据使用互斥锁?

PS:我在这个主题上找到的大多数答案都相当技术性,由于我不是这方面的专家,所以我更多地寻找一个概念性的答案。

【问题讨论】:

  • 任何可以有至少一个并发写入器/设置器与任何其他操作(另一个写入器/设置器或一些相关读取器/获取器)的任何东西都需要某种互斥锁定。我很难说得比这更简单。锁定的形式可能会有所不同,但这个概念实际上就是这么简单。未能提供排他性会降级为可能(并假设它们会)导致非确定性行为的竞争条件。

标签: c++ multithreading pthreads gtkmm


【解决方案1】:

如果您有从多个线程访问的数据,您可能需要一个互斥锁。你通常会看到类似的东西

theMutex.lock()
do_something_with_data()
theMutex.unlock()

或者更好的 c++ 习惯用法是:

{
    MutexGuard m(theMutex)
    do_something_with_data()
}

其中 MutexGuard c'tor 执行 lock() 而 d'tor 执行 unlock()

这条一般规则有一些例外

  • 如果您使用的数据可以以原子方式访问,则不需要锁。在 Visual Studio 中,您可以使用像 InterlockedIncrement() 这样的函数来执行此操作。 gcc 有它自己的设施来做到这一点。

  • 如果您访问数据只是为了读取它而从不更改它,那么不加锁通常是安全的。但是,即使单个线程对数据进行了任何更改,所有其他线程都需要确保它们在更改数据时不会尝试读取数据。您还可以阅读有关此类情况的 Reader-Writer 锁。

【讨论】:

  • 在不需要互斥体的情况下使用互斥体有什么缺点?
  • @joaocandre 当然,缺点是它增加了一些开销。然而,在大多数情况下,开销可以忽略不计。
  • 另一个问题,在您的示例中,以及velvetcache.org/2008/09/30/gtkmmglibmm-thread-example/… 中的教程中,我没有看到传递给互斥锁的有关要保护的数据/变量的信息。它如何知道要锁定哪些资源?
  • @joaocandre 互斥体不需要知道它保护什么。您仅在互斥锁被锁定时访问资源这一事实是保护数据的原因。互斥体的使用只允许单个线程进入正在处理数据的代码区域。这就是保护数据的原因。
【解决方案2】:

在多个线程之间更改的变量。所以未修改(不可变)的数据或未共享的数据不需要

【讨论】:

  • 嗨,欢迎来到 StackOverflow。你能重新格式化你的答案吗?这似乎对我有偏见。
猜你喜欢
  • 2013-12-10
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多