gpt4 book ai didi

c++ - 无等待或无锁初始化

转载 作者:行者123 更新时间:2023-11-30 02:48:59 25 4
gpt4 key购买 nike

我一直在研究惰性初始化(假设是全局变量,但它可以是任何东西)。到目前为止,我想出的是类似

enum state {
uninitialized,
initializing,
initialized
};
state s;
char memory[sizeof(T)];
T& initialize() {
auto val = compare_and_swap(&s, state::uninitialized, state::initializing);
if (val == initialized)
return *(T*)memory;
if (val == initializing) {
while(atomic_read(&s) != state::initialized);
return *(T*)memory;
}
new (memory) T();
atomic_write(&s, state::initialized);
return *(T*)memory;
}

在已经初始化的情况下,它是免等待的。但是我在一个线程正在初始化的情况下遇到了问题。完成初始化或等待初始化完成所需的步骤数与线程数不成比例。但是如果初始化线程被暂停,其他线程都必须任意等待直到它恢复。所以在一般情况下它不是无锁或无等待的。

是否可以创建无等待或无锁的惰性初始化?

最佳答案

如果您愿意初始化多个对象,那么您可以通过仅存储一个指针来编写无锁代码:

std::atomic<T *> p { nullptr };

T & get()
{
T * q = p.load();
if (!q)
{
T * r = new T;
if (p.compare_exchange_strong(q, r))
{
return *r;
}
else
{
delete r;
return *q;
}
}
return *q;
}

无锁算法的代价是你通常必须“尝试并失败”,所以即使你不得不丢弃结果,你也必须付出在本地尝试的代价。

正如您正确指出的那样,如果只有一个线程执行初始化,您将始终依赖于该单个线程,并且您不能无锁。


如果析构函数有副作用,您还需要相应的清理代码:

delete p.exchange(nullptr);

关于c++ - 无等待或无锁初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21649518/

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