Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 线程安全的唯一\u ptr移动_C++_C++11_Thread Safety_Move Semantics_Unique Ptr - Fatal编程技术网

C++ 线程安全的唯一\u ptr移动

C++ 线程安全的唯一\u ptr移动,c++,c++11,thread-safety,move-semantics,unique-ptr,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::unique_ptr DataManager::brooks

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

目前我有一个这样的代码

std::unique_ptr<SyncToken> DataManager::borrowSyncToken()
{
    std::unique_lock<std::mutex> syncTokenLock(syncTokenMutex);
    return std::move(syncToken);
}
std::unique_ptr DataManager::brooksynctoken()
{
std::unique_lock syncTokenLock(syncTokenMutex);
返回std::move(syncToken);
}
我想知道是否有更优雅的方式,比如简单地宣布:

std::atomic<std::unique_ptr<SyncToken>> syncToken;
std::原子同步令牌;
并且避免了互斥的需要。或者我根本不需要关心这里的锁,而std::move已经是原子的了

经过目前为止的研究,我觉得:

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

  • 不,这是不可能的

    传递给
    std::atomic
    的值
    T
    需要是可复制的,而
    std::unique\u ptr
    则不是。像
    std::atomic::load
    std::atomic::store
    这样的操作按值获取T个对象

    std::atomic
    中打包某些内容也不会使来自原子值的操作成为可能

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


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

    感谢您对std::shared_ptr的回答和讨论。出于目的:代码被简化了,但我认为即使如此,它也会将null ptr返回给以后的线程,从而允许调用方发现令牌不可用。这里解决的问题我将在其他评论中解释。客户机在DataManager上执行两种类型的操作:读取和写入。一次只能有一个客户机写入。客户端不是线程-有时是,有时可能会为客户端启动后台作业。读/写并不意味着简单的操作,而是遵循DataManager和客户端之间的复杂通信协议。在令牌可用之前,不一定要阻止客户端请求,但有时会主动拒绝。为了在混乱中定位,我提出了这个SyncToken-编写器需要借用SyncToken并在完成时调用returnSyncToken(unique_ptr)。