将多线程类重构为单线程+多线程类
Refactoring a multithreaded class into a single threaded + a multithreaded
我有一个这样实现的多线程c++类:
class MyClass{
protected:
somemutex mutex;
void _unsafeMethod(){...};
public:
void safeMethod{
locker lock(mutex);
_unsafeMethod();
}
}
我很高兴,但注意到,在大多数情况下,多线程支持并不是真正必要的,所以我想把它分成两个类:一个线程安全的,和一个不安全的,但性能更好的。
问题是,有成千上万行代码使用类,所以我需要保持接口相同。当然,类名将在其定义中更改,这取决于它是否需要支持MT。
我的想法是这样的:
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'。
你认为哪个解决方案更有效?你有更好/更干净/更有效的解决方案吗?
非常感谢!
一个简单的答案是将模板MyClass
设置为互斥锁类型:
template <typename MutexType>
class MyClass{
protected:
MutextType mutex;
public:
void safeMethod{
locker lock(mutex);
// stuff
}
}
然后你可以用一个真正的互斥锁或一个无操作的互斥锁实例化它来获得你想要的行为。
您可以使用装饰器模式或包装器。
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();
}
};
可以将互斥锁作为参数传递给构造函数。这将允许您选择锁定机制,而不必为您希望的每种锁定类型修改或复制实现。
class Mutex
{
public:
virtual void Lock() = 0;
};
class MyClass
{
protected:
Mutex& mutex;
public:
MyClass(Mutex& m) : mutex(m) {}
void Lock()
{
mutex.Lock();
}
};
相关文章:
- OpenMP:共享同一算法的单线程和多线程实现
- 重写多线程事件驱动的C 程序以使用单线程Boost :: Asio
- C++多线程操作比单线程慢
- 多线程和单线程代码维护
- 在 Linux 中从单独的单线程进程生成多线程进程时出现问题
- C++多线程性能比单线程代码慢
- 从单线程到多线程图像处理
- 多线程功能性能比单线螺纹差
- 单线程设计或多线程设计
- 与单线程相比,c++/java的多线程性能结果参差不齐
- C++中的单线程多线程代码
- C++线程-多线程比单线程慢
- 多线程与单线程快速排序花费相同的时间
- 为什么使用 pthread 的 Ubuntu 中的单线程比多线程快
- 为什么具有多线程的for循环的性能不如单线程
- 重构多线程方案的单线程 GUI 代码
- C++11 多线程比单线程慢
- 单线程和多线程代码需要同时花费时间
- GDB调试多线程,单线程无法预测执行
- 提振.Asio复合操作在单线程和多线程进程