std::shared_ptr::unique(),复制和线程安全
std::shared_ptr::unique(), copying and thread safety
我有一个 shared_ptr 存储在一个中央位置,多个线程可以通过方法 getPointer() 访问它。我想确保一次只有一个线程使用指针。因此,每当线程想要获取指针时,我都会通过 std::shared_ptr::unique() 方法测试中央副本是否是唯一的。如果它 return 是,我 return 副本假设 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;
}
此致
一次只能存在一个 "active" 副本。
它受互斥锁保护,直到创建第二个 shared_ptr
,此时后续调用(一旦它在第一个调用退出后获得互斥锁)将无法通过 unique
测试直到初始调用者返回的 shared_ptr
被销毁。
如评论中所述,unique
将在 c++20 中消失,但您可以测试 use_count == 1
,因为这就是 unique
所做的。
您的解决方案似乎过于复杂。它利用共享指针的内部工作原理来推断标志值。为什么不直接明确标记?
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., 如果你把它包装在 class 中,加上一些额外的花里胡哨,它会开始看起来很像 semaphore.
我有一个 shared_ptr 存储在一个中央位置,多个线程可以通过方法 getPointer() 访问它。我想确保一次只有一个线程使用指针。因此,每当线程想要获取指针时,我都会通过 std::shared_ptr::unique() 方法测试中央副本是否是唯一的。如果它 return 是,我 return 副本假设 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;
}
此致
一次只能存在一个 "active" 副本。
它受互斥锁保护,直到创建第二个 shared_ptr
,此时后续调用(一旦它在第一个调用退出后获得互斥锁)将无法通过 unique
测试直到初始调用者返回的 shared_ptr
被销毁。
如评论中所述,unique
将在 c++20 中消失,但您可以测试 use_count == 1
,因为这就是 unique
所做的。
您的解决方案似乎过于复杂。它利用共享指针的内部工作原理来推断标志值。为什么不直接明确标记?
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., 如果你把它包装在 class 中,加上一些额外的花里胡哨,它会开始看起来很像 semaphore.