一点一点的记录吧.
1.先说在线程中使用信号和槽的一些问题
1.1 connect的第五个参数[参考]
Qt::DirectConnection When emitted, the signal is immediately delivered to the slot. 假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这4个slot按连接的时间顺序调用一遍。显然这种方式不能跨线程(传递消息)。独立线程内的信号和槽连接方式,比如tcp/ip中的soket连接.
Qt::QueuedConnection When emitted, the signal is queued until the event loop is able to deliver it to the slot. 假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这个signal包装成一个 QEvent,放到消息队列里。QApplication::exec()或者线程的QThread::exec()会从消息队列里取消息,然后调用 signal关联的几个slot。这种方式既可以在线程内传递消息,也可以跨线程传递消息。
Qt::BlockingQueuedConnection Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different thread. Note that misuse of this type can lead to dead locks in your application. 与Qt::QueuedConnection类似,但是会阻塞等到关联的slot都被执行。这里出现了阻塞这个词,说明它是专门用来多线程间传递消息的。实现异步处理.
Qt::AutoConnection If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection. 这种连接类型根据signal和slot是否在同一个线程里自动选择Qt::DirectConnection或Qt::QueuedConnection, 这种方式是默认的连接方式.
emit 只有在run()里面才会是当作独立线程执行, 因为本质上SIGNAL和SLOT都是一个对象指针.
2.提升数据库的插入速度
解决方法:批处理+事务. 参考
SqlError addMessgeBatch( cosnt QVariantList& msgs)
{
QSqlDatabase db = QSqlDatabase::database();
db.transaction();//开启 事务
QSqlQuery q(db);
//[0]!批处理
q.prepare("INSERT INTO Tab_CANMessage VALUES (?,?,?)");
q.addBindValue(msgs);
if (!q.execBatch()){
qDebug() << q.lastError();
return q.lastError();
//[0]!批处理
}else{
db.commit();//提交
}
return QSqlError();
}
实测:5000条数据(20个字节的char*), 100ms左右.已经满足现在需求.