Qt:如果你过快地发送信号会发生什么?

4
这是情况:
  • 你有一个在后台线程中运行的长时间计算。
  • 这个计算每100毫秒发送一次信号,例如刷新GUI元素。
  • 假设它会发送100个这样的信号。
  • 被重新绘制的窗口需要超过100毫秒才能重新绘制,假设需要1秒钟。
在事件循环中会发生什么?信号调用是否会“堆积”直到它们全部执行(即100秒)?是否有任何机制可以“丢弃”事件?
2个回答

4
用户事件永远不会被丢弃。如果您将发出的信号事件排队比您处理它们的速度更快,则事件队列将增长,直到内存耗尽并导致程序崩溃。值得注意的是,若系统负载过重,QTimer 将跳过超时事件。在某种程度上,这可能有助于调节您的吞吐量。
您还可以考虑从一个线程向另一个线程发送反馈(例如确认),并根据消费者线程落后多少手动调整生产者线程的时间。或者,您可以使用“隐式阻塞调用”来完成这项工作。

3
在您的例子中,您可以在小部件中测量绘图时间。如果绘制例如需要240毫秒,则可以快速处理接下来的2个信号,而不必绘制任何内容。这样信号就不会积累。 编辑: 实际上,在我的解决方案中存在一些问题。最后一个信号应该总是引起重绘,否则当计算完成时,小部件将显示错误的数据。
当跳过信号时,可以启动一个单发定时器,例如间隔为150毫秒。当由于信号进行重绘时,此定时器将停止。因此,在最后一个重新绘制信号之后,此单发定时器将导致绘制最终状态。我想这会起作用,但这会相当复杂。
在计算开始时启动一个简单的定时器以执行重绘可能会是更好的方法。如果小部件的绘制需要很长时间,则可以根据绘制时间动态调整计时器间隔。

+1. 我认为我更喜欢这种解决方案,而不是我提出的任何东西。虽然,你可以进一步将计算频率与绘图频率完全解耦。只需缓存最后发出的值,并根据定时器重新绘制。 - cgmb
最佳方法真的取决于具体情况。如果需要不断重绘且重绘时间不长,则使用QTimer进行重绘将是简单而有效的解决方案。但是,如果通常根本不需要重绘,然后有突发变化需要进行相当重的重绘,则我提出的解决方案可能更好。 - user362638
我在我的解决方案中发现了一个问题,并向答案中添加了一些文本。 - user362638

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接