gpt4 book ai didi

c++ - 三重检查锁定?

转载 作者:搜寻专家 更新时间:2023-10-31 02:00:09 25 4
gpt4 key购买 nike

因此与此同时,我们知道双重检查锁定在 C++ 中不起作用,至少在可移植方式中不起作用。

我刚刚意识到我在用于地形光线追踪器的惰性四叉树中有一个脆弱的实现。因此,我试图找到一种仍然以安全方式使用惰性初始化的方法,因为我不想将内存使用量增加四倍并对大部分已实现的算法重新排序。

这种遍历的灵感来自 C++ and the Perils of Double-Checked Locking 第 12 页的模式,但尽量做到更便宜:

(pseudo code!)

struct Foo {
bool childCreated[4];
Mutex mutex[4];
Foo child[4];

void traverse (...) {
...
if (!childCreated[c]) {
// get updated view
#pragma flush childCreated[c]
if (!childCreated[c]) {
ScopedLock sl (mutex[c]);
if (!childCreated[c]) {
create (c);
#pragma flush childCreated[c]
childCreated[c] = true;
}
}
}
}
}

假设 #pragma flush 也将用作硬序列点,不允许编译器和处理器对它们之间的操作重新排序。

您看到了哪些问题?

编辑:版本 2,尝试考虑 Vlads 的回答(引入第三次刷新):

(pseudo code!)

struct Foo {
bool childCreated[4];
Mutex mutex[4];
Foo child[4];

void traverse (...) {
...
if (!childCreated[c]) {
// get updated view
#pragma flush childCreated[c]
if (!childCreated[c]) {
ScopedLock sl (mutex[c]);
#pragma flush childCreated[c]
if (!childCreated[c]) {
create (c);
#pragma flush childCreated[c]
childCreated[c] = true;
}
}
}
}
}

编辑: 第 3 版,我发现这与第 2 版非常等价,因为我没有使用 child 本身,而是使用原始标志来检查有效性,基本上依赖于创建之间的内存屏障一个 child 并写信给那面旗帜。

(pseudo code!)

struct Foo {
bool childCreated[4];
Mutex mutex[4];
Foo child[4];

void traverse (...) {
...
if (!childCreated[c]) {
ScopedLock sl (mutex[c]);
#pragma flush childCreated[c]
if (!childCreated[c]) {
create (c);
#pragma flush childCreated[c]
childCreated[c] = true;
}
}
}
}

最佳答案

看来你的模式不正确。考虑线程 #1 执行到第一个 #pragma flush 之后的情况。然后控制权切换到线程 #2,该线程继续并创建一个 c,控制权在第二个 #pragma flush 之前收回。现在第一个线程被唤醒,并重新创建子线程。

编辑:抱歉,错误:它将无法获取锁。

编辑 2:不,仍然正确,因为该值不会在线程 #1 中刷新

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

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