我正在做一个涉及使用多个线程的小项目。
C++ STD 库提供了不同的方法来防止undefined behavior
或data races
访问相同的内存块:
std::atomic
std::mutex
和std::lock_guard
现在,据我了解,您可以同时使用它们,结果几乎相同。两者都在线程使用时锁定资源并阻止另一个线程访问它。
不过,我的问题是:
我什么时候应该使用std::atomic
over什么std::mutex
时候应该使用std::mutex
over 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::mutex
和std::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_0
做RunThread_1
你想做的事:他们都调用Buffer::Write
方法来改变 member 的值Buffer::m_Data
。
最后的想法
我一直使用std::mutex
and std::lock_guard
,但我觉得std::atomic
它“更容易”使用,因为您不必担心丢失锁,而如果您使用std::mutex
,您可能会不小心错过一条std::lock_guard
语句,从而使数据竞争成为可能。
那么,使用std::atomic
over有优势std::mutex
还是只是设计问题?