最近做一个项目,采用Qt开发,在串口通讯采集与转发上要求高效率执行,发现效率不理想,
抛去串口返回响应时间的约束,程序逻辑实现上也花费了较长时间,最后定位在 QMutext为罪魁祸首。
项目一开始为了赶工,是这样使用QMutex的:
struc ValA
{
//
};
struc ValB
{
//
};
struc ValC
{
//
};
class A
{
public:
A(){};
void funcCall(){
m_Mutex_A.lock();
//iVal_A 相关逻辑处理
m_Mutex_A.unlock();
}
void funcA()
{
m_Mutex_A.lock();
if(condition(iVal_A 相关)){
m_Mutex_A.unlock();
//iVal_A 无关逻辑处理
funcCall();
}else{
m_Mutex_A.unlock();
}
}
void funcB()
{
//高优先级,必须每次获取到资源执行
m_Mutex_B.lock();
//iVal_B 相关逻辑处理
m_Mutex_B.unlock();
funcCall();
}
void funcC()
{
//低优先级,不执行也可以
m_Mutex_B.lock();
//iVal_B 相关逻辑处理
m_Mutex_B.unlock();
}
void funcD()
{
m_Mutex_C.lock();
//iVal_C 相关逻辑处理
if(condition1(iVal_C 相关))
m_Mutex_C.unlock();
return;
if(condition2(iVal_C 相关))
//iVal_C 相关逻辑处理
m_Mutex_C.unlock();
return;
......
//iVal_C 相关逻辑处理
m_Mutex_C.unlock();
}
private:
ValA iVal_A;
QMutex m_MutexA;
ValB iVal_B;
QMutex m_MutexB;
ValB iVal_C;
QMutex m_MutexC;
};
class ThreadA : public Thread
{
protected:
virtual void run()
{
while(condition){
funcA();
funcB();
funcD();
}
exec();
}
};
class ThreadB : public Thread
{
protected:
virtual void run()
{
while(condition){
funcA();
funcC();
funcD();
}
exec();
}
};
根据QMutex\QMutexLocker特性
1)QMutex::Recursive支持嵌套锁定
2)QMutex::trylock支持设定等待时间
3)QMutexLocker可简化互斥量的锁定和解锁操作
进行改造:
class A
{
public:
A():m_MutexA(QMutex::Recursive)//支持嵌套锁
{};
void funcCall(){
//iVal_A 相关逻辑处理
}
void funcA()
{
QMutexLocker locker(&m_MutexA);
if(condition(iVal_A 相关)){
//iVal_A 无关逻辑处理
funcCall();
}
}
void funcB()
{
//高优先级,必须每次获取到资源执行
m_Mutex_B.lock();
//iVal_B 相关逻辑处理
m_Mutex_B.unlock();
QMutexLocker locker(&m_MutexA);
funcCall();
}
void funcC()
{
//低优先级,不执行也可以
if(m_Mutex_B.trylock(100))//100毫秒外自动返回
{
//iVal_B 相关逻辑处理
m_Mutex_B.unlock();
}
}
void funcD()
{
QMutexLocker locker(&m_Mutex_C);//对于不断有返回的函数很有用
//iVal_C 相关逻辑处理
if(condition1(iVal_C 相关))
return;
if(condition2(iVal_C 相关))
//iVal_C 相关逻辑处理
return;
......
//iVal_C 相关逻辑处理
}
private:
ValA iVal_A;
QMutex m_MutexA;
ValB iVal_B;
QMutex m_MutexB;
ValB iVal_C;
QMutex m_MutexC;
};