gpt4 book ai didi

c++ - std::atomic_... 应该如何用于线程安全类的复制和移动操作?

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

我有以下类应该是线程安全的并且有一个 std::shared_ptr引用某些共享资源的成员。

class ResourceHandle
{
using Resource = /* unspecified */;
std::shared_ptr<Resource> m_resource;
};

多个线程可以从某个中央位置获取资源句柄的拷贝,中央资源句柄可以随时更新。因此,对同一个 ResourceHandle 的读取和写入可能会同时发生。

// Centrally:
ResourceHandle rh;

// Thread 1: reads the central handle into a local copy for further processing
auto localRh = rh;

// Thread 2: creates a new resource and updates the central handle
rh = ResourceHandle{/* ... */};

因为这些线程对同一个 std::shared_ptr 执行非常量操作, 根据 CppReference ,我应该使用 std::atomic_...<std::shared_ptr>操纵共享指针的专门化。

If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the shared_ptr overloads of atomic functions can be used to prevent the data race.

所以我想实现ResourceHandle的复制和移动操作使用这些原子操作的类,以便从多个线程操作单个资源句柄可以避免所有数据竞争。

CppReference page 的注释部分在 std::atomic_...<std::shared_ptr>专业说明如下:

To avoid data races, once a shared pointer is passed to any of these functions, it cannot be accessed non-atomically. In particular, you cannot dereference such a shared_ptr without first atomically loading it into another shared_ptr object, and then dereferencing through the second object.

所以我可能想使用 std::atomic_load 的某种组合和 std::atomic_store ,但我不确定应该在何时何地应用它们。

我的ResourceHandle的复制和移动操作应该如何实现类以不引入任何数据竞争?

最佳答案

std::shared_ptr 同步它对引用计数的访问,因此您不必担心对一个 std::shared_ptr 的操作会影响另一个。如果这些之后至少对指针对象进行了一次修改,那么您将有一场数据竞赛。那里。共享先前 Resource 所有权的代码将不受 m_resource 重置为指向新的 Resource 的影响。

如果可以在多线程中访问,则必须同步对单个 std::shared_ptr 的访问。提供的警告(以及它在 C++20 中被弃用的原因)指出,如果 anywhere 正在原子地访问一个值,则访问该值的 everywhere 应该是原子的。

您可以通过将全局 std::shared_ptr 隐藏在本地拷贝后面来实现。 ResourceHandle 作为一个单独的类使这变得更加困难。

using ResourceHandle = std::shared_ptr<Resource>;
static ResourceHandle global;

ResourceHandle getResource()
{
return std::atomic_load(&global);
}

void setResource(ResourceHandle handle)
{
std::atomic_store(&global, handle);
}

关于c++ - std::atomic_...<std::shared_ptr> 应该如何用于线程安全类的复制和移动操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55338588/

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