Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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++ std::shared_ptr::unique()、复制和线程安全_C++_Multithreading_Thread Safety_Std_Shared Ptr - Fatal编程技术网

C++ std::shared_ptr::unique()、复制和线程安全

C++ std::shared_ptr::unique()、复制和线程安全,c++,multithreading,thread-safety,std,shared-ptr,C++,Multithreading,Thread Safety,Std,Shared Ptr,我有一个存储在中心位置的共享_ptr,多个线程可以通过getPointer()方法访问它。我想确保一次只有一个线程使用指针。因此,每当线程想要获取指针时,我都会通过std::shared_ptr::unique()方法测试中心副本是否是唯一的副本。如果它返回yes,我将返回副本,假设unique()==false,只要该线程在副本上工作。其他试图同时访问指针的线程会收到一个null ptr,以后必须重试 现在我的问题是: 从理论上讲,调用getPointer()的两个不同线程是否有可能在互斥锁保

我有一个存储在中心位置的共享_ptr,多个线程可以通过getPointer()方法访问它。我想确保一次只有一个线程使用指针。因此,每当线程想要获取指针时,我都会通过std::shared_ptr::unique()方法测试中心副本是否是唯一的副本。如果它返回yes,我将返回副本,假设unique()==false,只要该线程在副本上工作。其他试图同时访问指针的线程会收到一个null ptr,以后必须重试

现在我的问题是:

从理论上讲,调用getPointer()的两个不同线程是否有可能在互斥锁保护和通过unique()进行测试的情况下相互访问指针

std::共享\u ptr myPointer;//我的指针在其他地方初始化,但在第一次调用getPointer()之前
std::mutex myMutex;
std::shared_ptr getPointer()
{
std::锁定保护(myMutex);
std::共享的返回值;
if(myPointer.unique())
returnValue=myPointer;
其他的
returnValue=nullptr;
返回值;
}
关于

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

它受互斥锁保护,直到创建第二个
共享\u ptr
后,随后的调用(在第一个调用退出后获得互斥锁)将无法通过
唯一测试,直到初始调用方返回的
共享\u ptr
被销毁


正如注释中所指出的,
unique
在c++20中即将消失,但是您可以测试
使用_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;
}
std::shared_ptr myPointer;
std::mutex myMutex;
bool mypointeriasise=false;
bool getPermissionToSemyPointer(){

std::lock\u guard链接的问题不包括std::shared\u ptr::unique和很少关于互斥体的内容。它也没有明确讨论我在这里列出的场景,特别是有问题的范围。请删除重复标记。注意。我无法提供原始代码,因为它很自信。提供的代码基本上是原始代码代码去除了所有分散问题注意力或是私密的代码。然后修改您的问题,询问所提供的代码,而不是参考一些模糊的未提供的代码。
std::shared_ptr::unique
在C++17中被弃用,在C++20中被删除。我建议避免使用它。@xaxxon是的,但只是因为临时返回lue在第一次调用后立即被销毁,因此我猜myMutex的引用计数返回1?是否保证myPointer的使用计数在保护被销毁之前增加?是的。一旦将其分配给returnValue,它就会增加,但即使没有显式执行,返回值也会在m之前创建utex已发布。您可以通过创建一个类型,在其构造函数/析构函数中打印日志信息,以显示构造/析构函数的相对顺序来向自己演示这一点。如果我删除返回值并立即返回会怎么样?返回值优化会对我造成影响吗?@Desperado17否,因为返回的共享\u ptr o仍然需要创建BUDC++,这会在MutExxGub被销毁之前增加UsHealCube,释放MutExu表示所提出的解决方案过于复杂,但在添加的状态信息中,当被释放的SydDypTR被破坏时,需要添加明确的清除调用。(据我所知)即使是,这也不是正确的逻辑,因为它将始终保持其当前值。仅将其赋值为true是正确的。非常具体地说,我对这个答案的主要问题是,它需要显式释放锁,而不是依赖“防护”-共享的ptr在保持使用计数方面的重要性。@xaxxon,这是一个公平的评估。如果我在这方面投入更多的精力,我可以将它变成一个RAII类,并解决您的一个问题。但是对于另一个问题,我真的不喜欢看到
共享的ptr以这种方式使用:它被用于两个不同的目的:(1)这是一个常见的角色,管理它所引用的对象的生命周期,(2)作为互斥体的一种奇怪的附属物。事实上,现在我想起来了,为什么OP需要
getPointer()
?为什么OP不简单地调用
myMutex::try_lock()
相反?整个情况都有一点代码味道,所以最好的解决方法有点模糊。很可能有一个基本的重新设计来解决这个问题,而不是解决这个特定问题的任何答案。我同意简单的互斥似乎就够了。
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;
}