问题描述:
我的工程使用UDP进行通信,初始程序运行正常。运行一段时间后,udp正常接收数据,并且成功将收到的数据发出信号,但是此时不执行槽函数。 并且界面出现卡死现象。
猜想可能:
线程阻塞、对象异常销毁(总感觉没有遇到过,后边发觉确实想多了)
后续解决:
1.使用数据库连接池的时候只是增加db,每次使用完毕未将db置为空闲状态,导致各个模块获取db并且db数据量大于等于最大连接数的时候,获取db的时候产生死循环等待。
2.多个模块共用一个线程,某几个模块耗时过长,导致接收数据槽函数的对象所在线程死锁。
3.某个模块使用数据库查询数据的时候使用while循环,每次循环将获取的数据不断发送前端,而我忘记对query进行break,导致后台不断向界面发送数据,界面卡死。(界面卡死的原因)
伪代码:
{ //改用数据库使用
db = getDb(); //获取db
use... db; //使用db
removeDb(&db);//移除db或者将db置为空闲状态。
}
{ //耗时线程单独开线程
Model modeRcv; //数据接收槽函数所在线程
Model_ modeOther;
//数据接收槽函数所在模块单独开辟一个线程
modeRcv.moveToThread(&thread1);
modeOther.moveToThread(&thread2);
}
补充:
后续遇到问题:当数据库异常的时候,整个后台处理变慢、甚至卡死。
原因:1.数据库读写和业务处理公用线程,当数据库异常的时候,db.open()函数的返回时间大于10s(可以通过函数设置,但是最少不低于2s),这些频繁open耗时过长导致程序卡顿。 2.获取db的操作使用了工具类实现,工具类中含有线程锁。当数据库异常的时候调用数据库连接清理函数的时候,导致死锁。即获取db的函数和清理连接函数公用一个锁,重复加锁导致死锁。
解决办法:1.将所有数据库操作单独放置一个线程:
优点:程序开启的线程少,消耗cpu较少。
缺点:操作数据库的模块划分耦合度会比较高。
2.在各个模块把数据库操作放入一个和业务不同的线程操作:
优点:各个模块耦合度比较低。
缺点:程序开启的线程多,消耗cpu较多。
3.去掉清理数据库连接函数中的加锁操作。