Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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++ 编译器生成的复制构造函数的线程安全性_C++_C++11 - Fatal编程技术网

C++ 编译器生成的复制构造函数的线程安全性

C++ 编译器生成的复制构造函数的线程安全性,c++,c++11,C++,C++11,我在做一些看似无害的事情 Foo*p=getAFoo()/*不是真的这么做,但在这里已经足够好了*/ Foo f(*p) 我依赖于编译器生成的复制构造函数Foo包含相当多的成员变量 在复制过程中,来自另一个线程的方法调用可能会修改*p的状态。我认为这会使f处于损坏状态 我是否需要自己编写复制构造函数并使用实例级互斥体?这将是一个令人头痛的问题,因为我在复制时很容易错过一个成员变量。复制构造函数不是线程安全的。所以,是的,您必须在这里使用互斥。但是请注意,修改状态的线程也必须使用互斥锁。仅在复制构

我在做一些看似无害的事情

Foo*p=getAFoo()/*不是真的这么做,但在这里已经足够好了*/

Foo f(*p)

我依赖于编译器生成的复制构造函数
Foo
包含相当多的成员变量

在复制过程中,来自另一个线程的方法调用可能会修改
*p
的状态。我认为这会使
f
处于损坏状态


我是否需要自己编写复制构造函数并使用实例级互斥体?这将是一个令人头痛的问题,因为我在复制时很容易错过一个成员变量。

复制构造函数不是线程安全的。所以,是的,您必须在这里使用互斥。但是请注意,修改状态的线程也必须使用互斥锁。仅在复制构造函数中使用互斥是不够的。

复制构造函数不是线程安全的。所以,是的,您必须在这里使用互斥。但是请注意,修改状态的线程也必须使用互斥锁。仅在复制构造函数中使用互斥体是不够的。

不,编译器生成的复制构造函数是不安全的,是的,您必须使用互斥体。更有趣的问题是把互斥锁放在哪里。您可以尝试将复制构造函数放入其中,但该方法可能无效且容易出错。假设您有以下代码:

Foo::Foo( const Foo &an )
{
    scope_lock( mutex );
}
首先,您将无法为成员使用复制构造函数,因为这将在锁定之前发生,因此您必须使用复制赋值,这很容易会降低效率。但还有一个更大的问题——如果Foo是从具有非平凡数据成员的类继承的。当您到达Foo的构造函数主体时,父类构造函数已经完成,所以您也有同样的问题

更好的解决方案是在语句
foof(*p)
及其修改位置周围使用互斥。这可以通过将Foo的copy-ctor设置为private/protected并创建一个方法copy(),该方法锁定实例互斥体,然后使用copy-ctor创建副本来实现:

Foo Foo::copy() 
{
    scope_lock( mutex );
    return *this;
}

更好的解决方案是重新设计您的程序,使这种情况根本不会发生。

不,编译器生成的复制构造函数是不安全的,是的,您必须使用互斥锁。更有趣的问题是把互斥锁放在哪里。您可以尝试将复制构造函数放入其中,但该方法可能无效且容易出错。假设您有以下代码:

Foo::Foo( const Foo &an )
{
    scope_lock( mutex );
}
首先,您将无法为成员使用复制构造函数,因为这将在锁定之前发生,因此您必须使用复制赋值,这很容易会降低效率。但还有一个更大的问题——如果Foo是从具有非平凡数据成员的类继承的。当您到达Foo的构造函数主体时,父类构造函数已经完成,所以您也有同样的问题

更好的解决方案是在语句
foof(*p)
及其修改位置周围使用互斥。这可以通过将Foo的copy-ctor设置为private/protected并创建一个方法copy(),该方法锁定实例互斥体,然后使用copy-ctor创建副本来实现:

Foo Foo::copy() 
{
    scope_lock( mutex );
    return *this;
}

更好的解决方案是重新设计程序,使这种情况根本不会发生。

解决方案是C++11。从可见副本构造函数委托给引用锁保护的私有构造函数:
Foo::Foo(const-Foo&other,std::lock\u-guard&&lock):stuff(other.stuff){}Foo::Foo(const-Foo&other):Foo(std::lock\u-guard(other.mutex),other){}/code>这作为注释是不可读的,我应该写一个答案。@Casey这怎么比
Foo Foo::copy(){scope_lock(mutex);return Foo(*this);}
?构造函数委托绝不比你的方法更干净。但是它使用了一个很酷的新功能,所以人们会喜欢它;-)@Slava:C++中复制对象的惯用方法是<代码> FoA= B;<代码>,而不是
Foo a=b.copy()。不支持惯用语法会导致各种问题,例如,如何复制
Foo
的容器?@Casey您的构造函数也不支持惯用语法,那么重点是什么呢?解决方案是C++11构造函数委托。从可见副本构造函数委托给引用锁保护的私有构造函数:
Foo::Foo(const-Foo&other,std::lock\u-guard&&lock):stuff(other.stuff){}Foo::Foo(const-Foo&other):Foo(std::lock\u-guard(other.mutex),other){}/code>这作为注释是不可读的,我应该写一个答案。@Casey这怎么比
Foo Foo::copy(){scope_lock(mutex);return Foo(*this);}
?构造函数委托绝不比你的方法更干净。但是它使用了一个很酷的新功能,所以人们会喜欢它;-)@Slava:C++中复制对象的惯用方法是<代码> FoA= B;<代码>,而不是
Foo a=b.copy()。不支持惯用语法会导致各种问题,例如,如何复制
Foo
的容器?@Casey您的构造函数也不支持惯用语法,那么重点是什么?