问题描述
我正在处理我的一个涉及使用多线程的小项目。
C++ STD 库提供了不同的方法来防止 undefined behavior
或 data races
访问同一内存块:
std::atomic
-
std::mutex
与std::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::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,20):
}
注意:RunThread_0
和 RunThread_1
执行您所期望的操作:它们都调用 Buffer::Write
方法来更改成员 Buffer::m_Data
的值。
最后的想法
我一直使用 std::mutex
和 std::lock_guard
,但我觉得 std::atomic
更“容易”使用,因为您不必担心丢失锁,而如果您使用std::mutex
您可能会意外错过 std::lock_guard
语句,从而导致数据竞争。
那么,使用 std::atomic
比使用 std::mutex
是否有优势,还是仅仅是设计问题?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)