gpt4 book ai didi

c++ - 在仅 move 类型上强制复制(然后销毁)

转载 作者:行者123 更新时间:2023-11-28 05:03:15 29 4
gpt4 key购买 nike

考虑以下无锁工作窃取 (de)que 函数:

template<class T>
inline T WorkStealQ<T>::Steal(void)
{
auto tail{_tail.load(std::memory_order_acquire)};
if (_head.load(std::memory_order_acquire) <= tail) return T();
auto task{_tasks[tail & _mask]};
if (_tail.compare_exchange_weak(tail, tail + 1, std::memory_order_release, std::memory_order_relaxed)) return task;
return T();
}

但是如果 T 只能 move 而不能复制怎么办?问题是从缓冲区读取项目是一个复制操作,不能更改为 auto task{std::move(_tasks[tail & _mask])}; 因为另一个并发操作也可以 move 它,在这种情况下,任何非只读但也修改原始构造函数(例如使指向资源的指针为空)的 move 构造函数都会破坏算法。

请注意,Steal() 的整体语义确实只执行从外部角度来看的 move ,因为只有一个并发操作会返回 T存储在该位置;任何其他输掉比赛的人都将无法通过 compare_exchange_weak()。因此,就用户而言,该操作不会破坏仅可 move T 的语义。不幸的是,在内部它需要对 T 做一个临时的浅拷贝,直到它决定是完成它作为 move 还是放弃,将它留在缓冲区中(它基本上是一个带有检查的两阶段 move 发生在中间)。

一种方法是将复制构造函数和复制赋值设为 T 的私有(private)成员,并有一个 friend WorkStealQ。问题是在我可能想用作 T 的第三方库类的情况下该怎么做。在这种情况下,除了使用指向此类对象的指针而不是侵入式存储它们(从而影响性能)之外,还有其他选择吗?我假设 memcpy 即使对于具有虚函数的类的浅拷贝也不起作用。

最佳答案

我认为您最好的选择可能是为每个 T 显式定义一个单独的 shallow_copy 类,并在您的工作窃取函数中使用它。这也将允许您处理导致您的类型只能 move 的任何问题(因为您无法事先知道临时拷贝将避免这些问题)。

关于c++ - 在仅 move 类型上强制复制(然后销毁),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45424024/

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