gpt4 book ai didi

c++ - 如何处理来自 Qt 中另一个线程的信号泛滥

转载 作者:太空狗 更新时间:2023-10-29 21:46:02 25 4
gpt4 key购买 nike

tl;dr:我有一个 QThread,只要有新数据可供处理,它就会向主线程发送信号。然后主线程获取、处理和显示数据。当主线程能够处理数据时,数据到达的频率更高,导致 GUI 卡住并最终导致堆栈溢出(耶!)。

详情

我的应用程序从相机获取帧以进行处理和显示。当新帧可用时,相机会通过 Windows 事件发出通知。我有一个线程定期检查这些事件并在新帧可用于抓取时通知主线程:

void Worker::run()
{
running_ = true;

while (running_)
{
if (WaitForSingleObject(nextColorFrameEvent, 0) == WAIT_OBJECT_0)
emit signalColorFrame();

usleep(15);
}
}

signalColorFrame 连接到 Camera 类中的插槽,该类从相机获取帧,进行一些处理并将其发送到绘制的 MainWindow它到屏幕上。

void Camera::onNewColorFrame()
{
getFrameFromCamera();
processFrame();
drawFrame();
}

现在,如果该方法在下一帧可用之前完成,则一切正常。随着处理变得越来越复杂,尽管 Camera 类会在处理完前一帧之前接收到新信号。

我的解决方案是在处理时阻止来自工作线程的信号,并强制偶数循环在 QCoreApplication::processEvents() 之间运行:

void Camera::onNewColorFrame()
{
worker_->blockSignals(true)
getFrameFromCamera();
processFrame();
drawFrame();
QCoreApplication::processEvents(); // this is essential for the GUI to remain responsive
worker_->blockSignals(false);
}

这看起来是个好方法吗?有人可以提出更好的解决方案吗?

最佳答案

我认为在解决技术方面的问题之前,您应该考虑考虑应用程序的设计方面。有几种方法可以解决您的问题,但首先您应该决定如何处理您没有时间在主线程中处理的帧。您是要跳过它们还是保存以供以后处理,但随后您应该意识到处理队列仍然必须有一定的大小限制,因此无论如何您应该决定如何处理“超出范围”的数据。

在这种情况下,我个人更喜欢制作一些中间容器来保存在某处接收到的数据,因此您的相机处理线程只通知收集器已收到数据,收集器决定是存储还是跳过数据。一旦有时间,主循环就会以 fetchNext() 或 fetchAll() 的形式访问收集器,具体取决于您的需要并实现对象处理。

关于c++ - 如何处理来自 Qt 中另一个线程的信号泛滥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16121024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com