线程安全unique_ptr移动

时间:2012-12-13 19:11:32

标签: c++ c++11 thread-safety move-semantics unique-ptr

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

目前我有一个像这样的代码

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

我想知道是否有更优雅的方式,比如简单地声明:

std::atomic<std::unique_ptr<SyncToken>> syncToken;

并避免使用互斥锁。或者我可能根本不需要关心这里的锁,std :: move已经是原子的吗?

到目前为止我做了研究后,在我看来:

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

1 个答案:

答案 0 :(得分:2)

不,这是不可能的。

您传递给T的值std::atomic需要轻易复制,std::unique_ptr不是。 std::atomic::loadstd::atomic::store等操作按值获取T对象。

std::atomic中打包某些东西也不会从值原子进行操作。

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

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