什么时候应该使用 `std::atomic`? 使用 std::atomic<Buffer>使用类成员 std::atomic<int> m_Data使用 std::mutex 和 std::lock_guard最后的想法

问题描述

我正在处理我的一个涉及使用多线程的小项目。

C++ STD 库提供了不同的方法来防止 undefined behaviordata races 访问同一内存块:

  • std::atomic
  • std::mutexstd::lock_guard

现在,根据我的理解,您可以同时使用它们,结果几乎相同。两者都在被线程使用时锁定资源并防止另一个线程访问它。

不过,我的问题是:

我什么时候应该使用 std::atomic 而不是 std::mutex,什么时候我应该使用 std::mutex 而不是 std::atomic


以这个简单的类为例。我有三种使用此类的方法来防止 data races:

使用 std::atomic<Buffer>

class Buffer {
  private:
    int m_Data;
  public:
    void Write(int data) {
      m_Data = data;
    }
    int Read() {
      return m_Data;
    }
}

int main() {
  std::atomic<Buffer> buffer;
  buffer.store(Buffer());

  RunThread_0(&buffer,10);

  RunThread_1(&buffer,20):
}

使用类成员 std::atomic<int> m_Data

class Buffer {
  private:
    std::atomic<int> m_Data;
  public:
    void Write(int data) {
      m_Data.store(data);
    }
    int Read() {
      return m_Data.load();
    }
}

int main() {
  Buffer buffer = Buffer();

  RunThread_0(&buffer,20):
}

使用 std::mutexstd::lock_guard

class Buffer {
  private:
    int m_Data;

    std::mutex m_DataMutex;

  public:
    void Write(int data) {
      const std::lock_guard<std::mutex> guard(m_DataMutex);
      m_Data = data;
    }
    int Read() {
      const std::lock_guard<std::mutex> guard(m_DataMutex);
      return m_Data
    }
}

int main() {
  Buffer buffer = Buffer();

  RunThread_0(&buffer,20):
}

注意:RunThread_0RunThread_1 执行您所期望的操作:它们都调用 Buffer::Write 方法来更改成员 Buffer::m_Data 的值。


最后的想法

我一直使用 std::mutexstd::lock_guard,但我觉得 std::atomic 更“容易”使用,因为您不必担心丢失锁,而如果您使用std::mutex 您可能会意外错过 std::lock_guard 语句,从而导致数据竞争。

那么,使用 std::atomic 比使用 std::mutex 是否有优势,还是仅仅是设计问题?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)