且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

QMutext 项目使用中的效率问题

更新时间:2022-06-27 11:16:40

最近做一个项目,采用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;
};