我有一个桌面应用程序(适用于Windows),它有一个普通的MainWindow
类,带有行编辑和标签等。没什么特别的。
这个UI类创建了一个派生自QThread的另一个类的实例,它有两个函数:
1-在.h文件中有静态系统调用(winapi)功能,该功能连接到通信设备的消息接收事件(连接也发生在api级别)
2-有一个无限循环(在QThread' s run
方法中)处理由中断处理程序放入队列的消息。
3-这两种方法中使用的静态消息队列受静态" QMutex
"和" QSemaphore
"在同一个类(message1553
)
调用启动线程的方法的MainWindow方法,也没有什么特别的。
void MainWindow::on_startTestButton_clicked()
{
msg1553 = new message1553();
msg1553->startBC();
}
启动设备的代码(和线程循环):
int message1553::startBC()
{
//some code to initialize and get the device going
is1553Running = true;
QThread::start(/*default priority*/);
return 1;
}
这是中断处理程序(位于message1553.h文件中),它将定期触发(由于在消息准备就绪时来自设备的某些系统调用):
static void __stdcall StatusResponseIRQ(S16BIT DevNum, U32BIT dwIrqStatus)
{
//...
if (sMsg.wType == ACE_MSG_RTTOBC)
{
mut.lock();
StatusMessage* gStatusMessage = new StatusMessage;
statusMessageQueue.enqueue(gStatusMessage);
sem.release();
mut.unlock();
//...
}
}
这是message1553
主题中的循环:
void message1553::run()
{
while(is1553Running)
{
if(!sem.tryAcquire())
{
continue;
}
else
{
mut.lock();
StatusMessage* stat = statusMessageQueue.dequeue();
mut.unlock();
emit invokeStatusMessageControls(stat);
}
}
}
message1553
类可以随时接收中断请求(实际上,它将以快节奏连续接收这些请求,即400个用户中的1条消息。)
message1553
线程循环将单独处理队列,一次获取1个项目,并通过信号将消息对象发送到MainWindow
(以便更新其GUI元素)。
现在,我将尝试列出我的发现:
1-每当我调整主窗口的大小时,都会遗漏一些中断消息(我可以通过监视消息中的消息编号来理解这一点。)
2-除非我与GUI混合,否则不会发生消息跳过。
3-(最奇怪的部分)我切断了MainWindow
和message1553
类之间的所有联系。我评论了" connect"线,"发出"行和任何声明。所有关系都被切断,保存MainWindow代码中message1553类的创建和起始行。但是,如果我调整MainWindow的大小/拖动,仍然会跳过消息。
4-如果我注释掉整个线程循环(在run
方法内),则不会发生问题。无论我对主窗口做什么,中断都可以正常工作。
5-我尝试更改message1553
线程的优先级,如果我将其提高得太高,则MainWindow会变得无法响应。如果我保持太低,仍然会遗漏消息。
6-我尝试在connect
方法中更改连接类型参数。尝试Qt::QueuedConnection
,Qt::BlockingQueuedConnection
等无济于事。一旦我开始调整主窗口的大小,就会跳过。
所有问题和调查结果都会导致一个核心问题:为什么MainWindow
事件循环及其活动会影响在后面工作的线程,该线程与MainWindow无关(除了在同一个域内运行)应用程序)?
我会感谢任何信息,任何观点或提示,一般或具体。我必须解决这个问题,并完整地接收所有消息,否则我的应用程序将有一个严重的错误。
感谢您的帮助。