gpt4 book ai didi

c++ - 双重检查锁定值变为空?

转载 作者:行者123 更新时间:2023-11-30 03:02:18 26 4
gpt4 key购买 nike

这个线程安全吗:

class X;

class Once {
public:
Once(X* x) : x_(x) {}

X* Get() {
if (!x_) return NULL;
// all dirty reads end up here.

// This could be any type of scoped lock...
some_scoped_lock lock(m);

// if (!x_) return x_; // omitted because it's a no op

X* ret(x_); // might get NULL if we waited for lock
x_ = NULL; // idempotent

return ret;
}

private:
X *x_;
some_kind_of_mutex m;

// Boilerplate to make all other constructors and default function private
....
}

(编辑:我对 c++11 和旧版本都感兴趣)

据我了解problem with Double-checked locking是在某些内存模型中,对 protected var 的写入可能会发生并尽早可见。我认为上面的代码没有这个问题,因为新值的有效性没有前提条件。我认为这是正确代码的唯一要求是,相对于构造函数中的写入和锁定下的写入,锁定下的所有读取必须是干净的。


更新:好的,这似乎会引发“未定义行为”陷阱,因此可以合法地做任何事情,包括耗尽您的银行账户。也就是说,在某些情况下它行为不端吗?

最佳答案

根据 C++11 标准,该行为是未定义的,因为存在数据竞争。更详细地说:线程 A 在 x_ = NULL 行中写入 x_,线程 B 在 if 行中从 x_ 读取(!x_) 返回 NULL。这两个操作没有顺序。这意味着存在数据竞争,这意味着未定义的行为。

您应该使用原子类型来避免数据竞争。这在您的示例中非常简单。但是,我认为这个问题更笼统。尽管如此:

struct Once
{
std::atomic<X*> _x;
explicit Once(X* x) : _x{x} {}
X* Get()
{
return _x.exchange(nullptr, std::memory_order::memory_order_relaxed);
}
};

关于c++ - 双重检查锁定值变为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10250043/

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