我对使用锁来保护我的共享数据结构有几个疑问。我正在使用 C/C++/ObjC/Objc++
例如我有一个在多线程环境中使用的计数器类
class MyCounter {
private:
int counter;
std::mutex m;
public:
int getCount() const {
return counter;
}
void increase() {
std::lock_guard<std::mutex> lk(m);
counter++;
}
};
我需要使用吗std::lock_guard<std::mutex> lk(m);
in getCount()
使其线程安全的方法?
如果只有两个线程会发生什么:读取器线程和写入器线程,那么我是否必须保护它?因为只有一个线程正在修改变量,所以我认为不会发生丢失更新。
如果共享基元类型变量有多个写入器/读取器(例如int
)如果只锁写方法而不锁读方法会发生什么灾难? 8 位类型与 64 位类型相比有什么区别吗?
任何原始类型默认都是原子的吗?例如写入一个char
总是原子的? (我知道这在 Java 中是正确的,但不知道 C++,如果平台很重要,我在 Mac 上使用 llvm 编译器)
是的,除非你能保证基础变量的变化counter
是原子的,你需要互斥锁。
经典的例子,说counter
是一个在(非原子)阶段递增的两字节值:
(a) add 1 to lower byte
if lower byte is 0:
(b) add 1 to upper byte
初始值为255。
如果另一个线程出现在低字节更改之间的任何位置a
和高字节变化b
,它将读取 0 而不是正确的 255(前增量)或 256(后增量)。
至于哪些数据类型是原子的,最新的 C++ 标准在<atomic>
header.
If you don't具有 C++11 功能,那么什么类型是原子的就取决于实现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)