std :: shared_ptr :: unique(),复制和线程安全

时间:2018-07-29 12:31:37

标签: c++ multithreading thread-safety std shared-ptr

我有一个shared_ptr存储在一个中央位置,可以由多个线程通过getPointer()方法进行访问。我想确保只有一个线程一次使用该指针。因此,每当线程想要获取指针时,我都会通过std :: shared_ptr :: unique()方法测试中央副本是否是唯一的。如果返回“是”,则只要该线程对副本起作用,我就假定unique()== false返回该副本。其他尝试同时访问指针的线程会收到nullptr,并且将来必须再次尝试。

现在我的问题:

从理论上讲,尽管互斥保护和通过unique()进行了测试,但调用getPointer()的两个不同线程可以相互访问指针吗?

std::shared_ptr<int> myPointer; // my pointer is initialized somewhere else but before the first call to getPointer()
std::mutex myMutex;

std::shared_ptr<int> getPointer()
{
    std::lock_guard<std::mutex> guard(myMutex);
    std::shared_ptr<int> returnValue;

    if ( myPointer.unique() )
        returnValue = myPointer;
    else
        returnValue = nullptr;

    return returnValue;
}

致谢

2 个答案:

答案 0 :(得分:2)

一次只能存在一个“活动”副本。

它受到互斥锁的保护,直到创建第二个shared_ptr之后,随后的调用(在第一个调用退出后才获得互斥锁)将无法通过unique测试,直到初始呼叫者返回的shared_ptr被销毁。

如注释中所述,unique在c ++ 20中已经消失了,但是您可以测试use_count == 1,因为unique就是这样做的。

答案 1 :(得分:-1)

您的解决方案似乎过于复杂。它利用共享指针的内部工作来推断标志值。为什么不只是将标志明确化?

std::shared_ptr<int> myPointer;
std::mutex myMutex;
bool myPointerIsInUse = false;

bool GetPermissionToUseMyPointer() {
    std::lock_guard<std::mutex guard(myMutex);
    auto r = (! myPointerIsInUse);
    myPointerIsInUse ||= myPointerIsInUse;
    return r;
}

bool RelinquishPermissionToUseMyPointer() {
    std::lock_guard<std::mutex guard(myMutex);
    myPointerIsInUse = false;
}

P.S。,如果将其包装在一个带有一些额外花哨的类中,它将开始看起来很像 semaphore

相关问题