我有一个以这种方式实现的多线程c ++类:
class MyClass{
protected:
somemutex mutex;
void _unsafeMethod(){...};
public:
void safeMethod{
locker lock(mutex);
_unsafeMethod();
}
}
我对此感到高兴,但注意到在大多数情况下,多线程支持并不是必需的,所以我很乐意将它分成两类:一个线程安全的,一个不安全的,但性能更好之一。
问题是,使用该类有数千行代码,所以我需要保持接口相同。当然,类名将根据其是否需要支持MT而改变其定义。
我想到了以下内容:
解决方案A
class MyClass{
protected:
void _unsafeMethod(){...};
public:
virtual void safeMethod{
_unsafeMethod()
};
};
class MyThreadSafeClass: public MyClass{
protected:
somemutex mutex;
public:
virtual void safeMethod{
locker lock(mutex);
_unsafeMethod();
};
}
这里的问题是虚函数调用:它是否会使执行速度变慢,所以我立即失去了单线程类性能提升的好处?从第一次测试看起来像
解决方案B
class MyClass{
protected:
somemutex * pmutex;
void _unsafeMethod(){...};
public:
MyClass( bool isthreadsafe ){
if( isthreadsafe )
pmutex = new somemutex();
else
pmutex = NULL;
};
void safeMethod{
if( pmutex )
{
locker lock(*pmutex);
_unsafeMethod();
}
else
_unsafeMethod();
};
}
这第二个解决方案看起来很脏,每个调用中都有一个'if'可以解决。
您认为哪种解决方案更有效?你有没有更好/更清洁/更好的解决方案?
非常感谢!
答案 0 :(得分:3)
直接的答案是在互斥锁类型上模板MyClass
:
template <typename MutexType>
class MyClass{
protected:
MutextType mutex;
public:
void safeMethod{
locker lock(mutex);
// stuff
}
}
然后,您可以使用真实互斥锁或无操作互斥锁实例化它,以获得您想要的行为。
答案 1 :(得分:2)
您可以使用装饰器模式或包装器。 。
A ]修改后的包装器,以便您可以使用虚拟函数:
class MyClass{
protected:
void _unsafeMethod(){};
};
class MyThreadSafeClass{
protected:
somemutex mutex;
MyClass& myclassRef;
public:
MyThreadSafeClass(MyClass& myclass):myclassRef(myclass){}
void safeMethod(){
locker lock(mutex);
myclassRef._unsafeMethod();
}
};
类调用:
MyClass myclass;
MyThreadSafeClass mythreadsafeclass(myclass);
mythreadsafeclass.safeMethod();
B ]具有虚拟界面的装饰器:
class MyClassInterface{
public:
virtual void Method()=0;
};
class MyClass : public MyClassInterface{
protected:
virtual void Method() override{};
};
class MyThreadSafeClass: public MyClassInterface{
protected:
somemutex mutex;
MyClassInterface& myclassRef;
public:
MyThreadSafeClass(MyClassInterface& myclass):myclassRef(myclass){}
virtual void Method() override{
locker lock(mutex);
myclassRef.Method();
}
};
答案 2 :(得分:1)
您可以将互斥锁作为参数传递给构造函数。这将允许您选择锁定机制,而无需修改或复制您希望的每种锁定类型的实现。
class Mutex
{
public:
virtual void Lock() = 0;
};
class MyClass
{
protected:
Mutex& mutex;
public:
MyClass(Mutex& m) : mutex(m) {}
void Lock()
{
mutex.Lock();
}
};