我做的事情似乎无关紧要
Foo* p = getAFoo(); /*not really doing this but good enough here*/
Foo f(*p);
我依赖编译器生成的复制构造函数。 Foo
包含相当多的成员变量。
来自另一个线程的方法调用可能会在复制期间修改*p
的状态。我认为可能会使f
处于损坏的状态。
我是否需要自己编写复制构造函数并使用实例级互斥?这将是一个令人头疼的问题,因为我在拍摄副本时很容易错过成员变量。
答案 0 :(得分:4)
复制构造函数不是线程安全的。所以,是的,你必须在这里使用互斥锁。但请注意,修改状态的线程也必须使用互斥锁。仅在复制构造函数中使用互斥锁是不够的。
答案 1 :(得分:2)
不,编译器生成的拷贝构造函数不安全,是的,你必须使用互斥锁。更有意思的问题是将互斥锁置于何处。您可能会尝试放入复制构造函数体,但该方法可能无效并且容易出错。我们假设你有这个代码:
Foo::Foo( const Foo &an )
{
scope_lock( mutex );
}
首先,您将无法为成员使用复制构造函数,因为这将在锁定之前发生,因此您将不得不使用复制赋值,这很容易降低效率。但是甚至还有一个更大的问题 - 如果Foo是从具有非平凡数据成员的类继承而来的。当你到达Foo构造函数的主体时,父类构造函数已经完成,所以你有同样的问题。
更好的解决方案是在语句Foo f(*p)
周围使用互斥锁以及修改它的位置。这可以通过使Foo的copy ctor private / protected并创建一个方法copy()来锁定实例互斥然后使用copy ctor创建一个副本来实现:
Foo Foo::copy()
{
scope_lock( mutex );
return *this;
}
更好的解决方案是重新设计您的程序,这种情况根本不会发生。