gpt4 book ai didi

c++ - 无锁代码中的延迟初始化

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:26:01 25 4
gpt4 key购买 nike

假设我有一个原子指针:

std::atomic<void*> mItems;

在一个函数中,当一个线程需要访问它时,它首先检查它,如果它是空的,线程将为它分配内存:

void* lItems = std::atomic_load_explicit(&mItems, memory_order_relaxed);
if(lItems == nullptr)
{
void* lAllocation = malloc(...);

if(!std::atomic_compare_exchange_strong_explicit(
&mItems,
&lItems,
lAllocation,
memory_order_relaxed,
memory_order_relaxed))
{
free(lAllocation);
}
}
...

但是,如果 N 个线程并发运行此方法并看到 mItems 等于 null,则所有线程都将分配内存,并且其中 N - 1 个将再次释放。

我如何用更好的方法编写类似的方法。

最佳答案

我猜你可以让指针成为你的互斥量,使用一些众所周知的值(比如,全局地址)作为标志,表明其他线程已经在进行分配。

因此,您的值是:NULL -> 神奇的“正在进行的分配”指针 -> 实际分配。

代码会做这样的事情:

  • 加载地址:它将具有以下值之一:
    1. NULL:具有魔法值的 CAS
      • CAS 成功了吗?如果是,我们正在做分配,每个人都知道
        • 进行分配,存储新地址,我们就完成了(不必对它进行 CAS,因为我们已经保证用第一个 CAS 排除)
      • 不是,那是别人在做分配,回到1
    2. 地址不是NULL,而是魔法值
      • 所以有人已经在进行分配 - 只需等到它发生变化,然后使用最终值
    3. 既不是 NULL 也不是魔术,所以它已经是一个真正的分配值 - 只需使用它

这样只有一个线程进行分配,但您的其他 N-1 个线程可能正忙于等待。这是否真的更好会有所不同......

关于c++ - 无锁代码中的延迟初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19244697/

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