【发布时间】:2015-06-18 09:41:22
【问题描述】:
Jeff Preshing 的 article 声明双重检查锁定模式 (DCLP) 在 C++11 中是固定的。用于此模式的经典示例是单例模式,但我碰巧有一个不同的用例,我仍然缺乏处理“原子武器”的经验——也许这里有人可以帮助我。
以下代码是 Jeff 在"Using C++11 Sequentially Consistent Atomics" 下描述的正确 DCLP 实现吗?
class Foo {
std::shared_ptr<B> data;
std::mutex mutex;
void detach()
{
if (data.use_count() > 1)
{
std::lock_guard<std::mutex> lock{mutex};
if (data.use_count() > 1)
{
data = std::make_shared<B>(*data);
}
}
}
public:
// public interface
};
【问题讨论】:
-
如果您使用互斥锁保护
data,则不需要atomic_store。 -
use_count是const,所以按照一般的库规则,并发调用它不会导致数据竞争。 -
@KerrekSB 我在 Herbs talk 中听说了
const的评论。你真的会假设这条规则得到普遍执行吗?感谢您对不必要的atomic_store的提示 - 我忽略了这一点。 -
嗯,[res.on.data.races]/2 要求 const 成员函数不修改对象。但是,这有点不清楚,因为复制
data显然会改变使用次数。但是复制构造函数需要一个 const 值,所以我认为这不构成与数据竞争相关的修改。在实践中,我希望这是无数据竞争的,但据我所知,标准并不完全清楚。 -
啊,没关系。首先,引用的段落基本上说复制构造函数不会“修改”参数(因为它是 const)。 [util.smartptr.shared]/4 中有一个说明:“为了确定是否存在数据竞争,成员函数应仅访问和修改
shared_ptr和weak_ptr对象本身,而不是它们引用的对象。use_count()中的更改不反映可能引入数据竞争的修改。”
标签: c++ multithreading c++11