gpt4 book ai didi

c++ - 我的双重检查锁定模式实现是否正确?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:45:31 24 4
gpt4 key购买 nike

Meyers 的书 Effective Modern C++ 中的一个示例,第 16 项。

in a class caching an expensive-to-compute int, you might try to use a pair of std::atomic avriables instead of a mutex:

class Widget {
public:
int magicValue() const {
if (cachedValid) {
return cachedValue;
} else {
auto val1 = expensiveComputation1();
auto val2 = expensiveComputation2();

cachedValue = va1 + val2;
cacheValid = true;
return cachedValue;
}
}
private:
mutable std::atomic<bool> cacheValid { false };
mutable std::atomic<int> cachedValue;
};

This will work, but sometimes it will work a lot harder than it should.Consider: A thread calls Widget::magicValue, sees cacheValid as false, performs the two expensive computations, and assigns their sum to cachedValud. At that point, a second thread calss Widget::magicValue, also sees cacheValid as false, and thus carries out the same expensive computations that the first thread has just finished.

然后他给出了一个带有互斥量的解决方案:

class Widget {
public:
int magicValue() const {
std::lock_guard<std::mutex> guard(m);
if (cacheValid) {
return cachedValue;
} else {
auto val1 = expensiveComputation1();
auto val2 = expensiveComputation2();

cachedValue = va1 + val2;
cacheValid = true;
return cachedValue;
}
}
private:
mutable std::mutex m;
mutable bool cacheValid { false };
mutable int cachedValue;
};

但我认为解决方案不是那么有效,我考虑将互斥锁和原子结合起来组成一个双重检查锁定模式,如下所示。

class Widget {
public:
int magicValue() const {
if (!cacheValid) {
std::lock_guard<std::mutex> guard(m);
if (!cacheValid) {
auto val1 = expensiveComputation1();
auto val2 = expensiveComputation2();

cachedValue = va1 + val2;
cacheValid = true;
}
}
return cachedValue;
}
private:
mutable std::mutex m;
mutable std::atomic<bool> cacheValid { false };
mutable std::atomic<int> cachedValue;
};

因为本人是多线程编程新手,所以想了解:

  • 我的代码正确吗?
  • 它的性能更好吗?

编辑:


修复了代码。if (!cachedValue) -> if (!cacheValid)

最佳答案

正如 HappyCactus 所指出的,第二个检查 if (!cachedValue) 实际上应该是 if (!cachedValid)。除了这个错字外,我认为您对双重检查锁定模式的演示是正确的。但是,我认为没有必要在cachedValue 上使用std::atomic。唯一写入 cachedValue 的地方是 cachedValue = va1 + val2;。在完成之前,任何线程都不会到达语句 return cachedValue;,这是唯一读取 cachedValue 的地方。因此,写入和读取不可能并发。并且并发读取没有问题。

关于c++ - 我的双重检查锁定模式实现是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30048216/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com