3

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

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

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

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

不过,我的问题是:

我什么时候应该使用std::atomicover什么std::mutex时候应该使用std::mutexover 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, 10);

  RunThread_1(&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, 10);

  RunThread_1(&buffer, 20):
}

注意:RunThread_0RunThread_1你想做的事:他们都调用Buffer::Write方法来改变 member 的值Buffer::m_Data


最后的想法

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

那么,使用std::atomicover有优势std::mutex还是只是设计问题?

4

0 回答 0