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您的构造函数也不支持惯用语法,那么重点是什么?