我有一个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;
}
致谢
答案 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 。