【问题标题】:Multithreading - synchronised value vs mutexes?多线程 - 同步值与互斥锁?
【发布时间】:2021-06-04 22:57:00
【问题描述】:

在编写多线程代码时,我经常需要读取/写入共享内存。为了防止数据争用,首选的解决方案是使用lock_guard 之类的东西。但是最近,我遇到了“同步值”的概念,它通常以以下方式实现:

template <typename T>
class SynchronizedValue {
    T value;
    std::mutex lock;
    /* Public helper functions to read/write to a value, making sure the lock is locked when the value is written to*/
};

此类同步值将有一个方法SetValueTo,该方法将锁定互斥体、写入值并解锁互斥体,确保您可以安全地写入值而不会发生任何数据争用。

这使得编写多线程代码变得非常容易!但是,与互斥锁/lock_guard 相比,使用这些同步值是否有任何缺点/性能开销?

【问题讨论】:

  • 您能否提供不使用上述同步值的等效代码?也就是说,如果您使用大量锁是因为不同的线程竞争(!)共享资源,您应该重新考虑您的设计。而是沟通和合作。这与你的问题无关,但我感觉你的方向错了。
  • @UlrichEckhardt 这只是一个纯粹出于好奇的一般 c++ 问题,因为我试图理解多线程......我现在什至没有在我的项目中使用多线程! :)
  • @UlrichEckhardt 带有 lock_guard 的代码将只有一个全局互斥锁,并在每个多线程函数的开头实例化一个 lock_guard。

标签: c++ multithreading concurrency shared-memory


【解决方案1】:

如果您深入了解每种情况下实际发生的情况,您会发现说和做同一件事的不同方式。

【讨论】:

    【解决方案2】:

    使用这些SynchronisedValues...有什么缺点/性能开销吗?

    在你问有没有缺点之前,你首先应该问有没有好处。标准 C++ 库已经定义了std::atomic&lt;T&gt;。您没有说出您的想法/* public helper functions...*/,但如果他们只是value 的getter 和setter,那么您的SynchronizedValues&lt;T&gt; 课程提供了您尚未从std::atomic&lt;T&gt; 获得的什么?


    顺便说一句,“原子”变量不能消除对互斥锁的需求的一个重要原因。互斥锁不仅仅是为了确保内存更新的“可见性”:考虑互斥锁的最重要方式是它们可以保护程序中数据之间的关系

    例如,想象一个程序有多个容器来存放某类对象,想象程序需要将对象从一个容器移动到另一个容器,并想象某个线程偶尔计数 all很重要> 的对象,并保证得到准确的计数。

    程序可以使用互斥锁来实现这一点。它只需要遵守两个简单的规则; (1) 任何线程都不能从任何容器中删除对象,除非它已锁定互斥锁,并且 (2) 任何线程都不能释放互斥锁,直到每个对象都在容器中。如果所有线程都遵守这两个规则,那么如果在开始计数之前锁定互斥锁,那么计数对象的线程可以保证找到所有对象。

    问题是,您不能仅通过将所有变量设为atomic 来保证这一点,因为atomic 不会保护所讨论的变量与任何 之间的任何关系 >其他变量。最多,它只保护变量值在一些“原子”操作(例如原子增量)之前和之后的关系。

    如果有多个变量参与关系,那么您必须有一个互斥锁(或等同于互斥锁的东西。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 1970-01-01
      相关资源
      最近更新 更多