假设我有一个单例内存(意味着我只写入一次)。假设我有
Calculator
和 Printer
。 Calculator
管理 Printer
,但在构建时无权访问它。
class Printer;
class Calculator {
void read() {
int result = 0;
if (_printer != nullptr) {
_print(result);
}
}
// Assume `Printer` passed to us is unique
void write(Printer* printer) {
std::lock_guard<std::mutex> lock(_lock);
if (_printer == nullptr) {
_printer = printer;
}
}
std::mutex _lock;
Printer _printer{nullptr};
}
如您所见,我们只会初始化内存一次。因此,要么
_printer
是 null
(这是可以的),要么 _printer
内存存在,并且我们知道通过单例设计,内存不会因未来的写入而失效。
此时读取内存是否安全,或者线程竞争仍然会导致崩溃吗?
不,这是数据竞争的未定义行为。
即使
write
仅被调用一次,您也需要确保与任何可能的 read
调用同步。否则,有可能 read
正在读取指针值,而单个 write
正在写入指针值。互斥体不会强加任何同步,因为您没有将其锁定在 read
。
让一个线程读取非原子对象,而另一个线程在不同步的情况下写入该对象,这是一种数据竞争,这始终是未定义的行为。
争论
if
中指针的可能值是没有意义的。读取值本身就是一种数据竞争并导致未定义的行为。