【问题标题】:Mutexes with variables in struct结构中带有变量的互斥锁
【发布时间】:2018-10-12 23:00:57
【问题描述】:

我正在开发一个使用多个线程的项目,这些线程可以访问包含多个变量的共享结构。

为了避免并发问题,每当对共享结构中的一个变量进行写入时,我都会使用互斥锁。现在我为每个变量使用不同的互斥锁,这样我就可以避免锁定一个线程来尝试写入一个没有被写入的变量,但我想知道是否有更好的方法来避免这个问题。

另外,考虑到我的结构有 uint16_t 变量,由于内存对齐和存储在同一数据寄存器上的多个变量,我应该采取什么额外措施来保证线程间的数据一致性?

谢谢。

【问题讨论】:

  • "...但我想知道是否有更好的方法来避免这个问题。" - 对所有变量使用单个互斥体,因为它更简单。请注意,在优化性能之前,您需要像往常一样首先测量该性能。至于从不同的互斥体访问不同的结构体字段,请看那个问题:stackoverflow.com/questions/47008183/…

标签: multithreading struct alignment mutex atomic


【解决方案1】:

你没有说什么语言。我会假装它是 C++。

我为每个变量使用不同的互斥锁...

这听起来很可疑。

您的线程通过更新共享状态相互通信。正确使用互斥锁会做两件事:

  • 确保线程 A 更新共享状态后,其他线程将能够看到更改的内容,并且
  • 它确保其他线程不会看到更改,直到更改完成

如果一个线程可以通过写一个uint16_t 值来有意义地改变程序的状态,那么你就不需要互斥体了。只需将变量的类型更改为atomic<uint16_t>. 使其成为原子将确保其他线程可以看到更改。而且,您不必担心完整性。这很简单:每个其他线程都必须看到旧值或新值。没有其他可能。

当情况更复杂时,您需要mutex。假设你有三个变量:

int a, b, c;

并且,假设有一条规则,a+b+c 必须始终等于 0。这样的规则称为不变量。现在,一个线程不可能合法地改变这三个变量中的一个。但是,如果它试图连续更改其中的两个,总是有可能其他线程可能会在错误的时刻查看它们,并且它可能会看到它们处于不一致的状态(即,处于破坏不变。)

使变量atomic 不会解决问题。而且,为每个变量创建一个单独的互斥锁 不会解决问题。您需要 一个 互斥体,其目的是保护不变量。您需要更新ab 和/或c 的每个线程来锁定该互斥体,只要它进行更改;并且您需要每个期望不变量为真的线程在查看它们时锁定相同的互斥锁。

【讨论】:

    猜你喜欢
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 2012-06-05
    • 1970-01-01
    相关资源
    最近更新 更多