使用QT做TCP socket通信的案例。
1、多线程机制,包括主线程UI、数据接收线程、报警线程、数据库线程,线程间采用信号槽通信;
2、UI线程中使用QTreeWidget动态显示所有socket的状态参数信息;
3、UI线程轮转显示报警信息;
4、数据库(使用sqlite3数据库)线程插入报警信息前,会使用到QMutexLocker锁,其它线程均未使用锁;
5、数据库线程间隔10s插入一次当前所有的报警信息,而不是一产生报警就往数据库里面塞数据,防止操作数据库过于频繁。使用局部QSqlQuery对象进行数据库操作exec来插入报警数据,操作前会先开启事务(QSqlDatabase transaction),所有插入操作执行后会提交事务(QSqlDatabase commit)。
问题:程序运行三天左右,UI界面会无故卡死,点击界面无响应,会转圈圈,且没有任何错误信息,再次点击界面会弹出结束程序的对话框。此时通过预先设定好的qDebug调试分析:
1、数据接收线程正常工作,数据接收线程接收到的socket状态参数信息无法发送至UI界面(无法connect至UI对应的槽函数);
2、数据接收线程和报警线程均正常工作,数据接收线程接收到socket报警信息可以正常发送至报警线程,但报警线程无法发送至数据库线程(无法connect至数据库对应的槽函数);
个人分析:
1、UI界面可以排除内存泄漏的问题,QTreeWidget在定时显示所有的socket状态参数信息前会删除上次所有创建的指针对象(指针对象delete后再将指针置为NULL),然后再进行本轮的显示(创建所有指针对象),因此不会有内存泄漏的问题;
2、每次卡死的时机,经过观察都是在网络不稳定时,socket信息发生变化,进而导致QTreeWidget中的信息频繁变化导致界面卡死,但大部分时间(网络平时也会不稳定)是不会出问题的,运行几天后才会特别偶发卡死一次;
3、会不会是数据库线程执行局部QSqlQuery的exec时候阻塞了?
请教大家有没有遇到类似的问题?应该怎么去排查定位问题(怀疑是数据库线程或UI线程的问题)。