线程安全unique_ptr移动

Dav*_* L. 5 c++ thread-safety unique-ptr move-semantics c++11

是否可以使用c ++ 11原子操作安全地移动unique_ptr?

目前我有这样的代码

std::unique_ptr<SyncToken> DataManager::borrowSyncToken()
{
    std::unique_lock<std::mutex> syncTokenLock(syncTokenMutex);
    return std::move(syncToken);
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一些更优雅的方式,就像简单地声明:

std::atomic<std::unique_ptr<SyncToken>> syncToken;
Run Code Online (Sandbox Code Playgroud)

并避免使用互斥量.或者我可能根本不需要关心锁定而且std :: move已经是原子的?

经过研究,我到目前为止在我看来:

  • std :: move本身不是原子的,需要有一些同步,否则2个线程同时调用我的方法可能最终得到2个未定义指针的副本.
  • std :: atomic声明为我编译,但我不知道如何初始化它并进行移动.

inf*_*inf 3

不,这是不可能的。

T您传递给的值std::atomic需要是可简单复制的,但事实std::unique_ptr并非如此。std::atomic::load类似或std::atomic::store按值获取 T 对象的操作。

将某些内容打包在 a 中std::atomic也不会使值的操作变得原子。

在原子上下文中使用时std::unique_ptr,您必须考虑在管理资源时可能会遇到问题的事实。你永远不知道有多少线程仍然引用你的数据,这个问题可以通过std::shared_ptr使用原子引用计数来解决。(您需要使用该std::atomic_is_lock_free函数检查它是否真的是原子的。)

在查看代码时我也偶然发现的一件事是该borrowSyncToken函数的意图。这称为借用,但您通过移出 来将令牌的所有权传递给调用者std::unique_ptr,所有权如何传回,以及当 DataManager 当前不拥有令牌时其他线程会得到什么?