问题描述
使用Qt开发,App通过uart向基板发送uart命令。想在两个命令间加上10ms延时,代码如下:
char cMessage[4];
...
...
m_serialPort->write(cMessage,4);
usleep(10000);
m_serialPort->write(cMessage,4);
但实际执行的情况是先延时10ms,再执行两次uart发送。
原因分析
第一次uart发送的命令进入程序的消息队列等待执行,但接下了的sleep操作导致消息执行被阻塞。直到sleep结束后,才会去执行第一次的uart操作。
解决方案
方案1
char cMessage[4];
...
...
m_serialPort->write(cMessage,4);
m_serialPort->waitForBytesWritten(10000);//等待系统把串口数据发送完成
usleep(10000);
m_serialPort->write(cMessage,4);
waitForBytesWritten()函数会等待操作系统把uart数据发送完毕后才返回,函数的输出参数为等待时间,单位ms。
方案2
char cMessage[4];
...
...
m_serialPort->write(cMessage,4);
QTime t;
t.start();
while(t.elapsed()<5000);
{
qApp->processEvents();//执行消息队列中的所有事件
}
m_serialPort->write(cMessage,4);
在循环中不断执行qApp->processEvents()以使整个App界面不卡死,能正常响应外接操作。
总结
不仅是延时函数会导致消息队列卡死,在处理一些会耗时的操作时,都会遇到这类问题。所以能够在耗时的操作中不断执行qApp->processEvents()是可以达到app不卡顿的效果的,但更好的处理方法还是将耗时的操作放到一个新开的工作线程中处理比较好。