HY。
我甚至不确定如何为这个问题形成标题。
制片: 我有一个案例,我想在屏幕上显示一些数据,但每次用户与窗口交互时都需要重新计算。对于单击,拖动或滚轮事件,我发送一个请求重新计算的信号。因此,对于旋转(拖动事件),可以发出数十个请求。但是如果数据已经重新计算,procces必须停止并重新启动。重新计算可能需要10毫秒到5秒。然后使用信号量/互斥量我在数据就绪时在鼠标光标上显示一些信息。
消费者: 应该收到重新计算的请求并开始重新计算。还应该停止以前的任何计算。当计算超过解锁互斥锁/信号量时。
我一直在思考和谷歌搜索,但仍然无法找到解决此问题的完美解决方案。你能否指出一些可能适用于这种情况的通用解决方案。
我认为有关QT信号和插槽系统的一些事实与此问题有关: - 执行计算时,eventloop不活动,因此在计算完成之前不会执行插槽 - 一次一个地执行插槽
我的解决方案是在主线程中使用Consumer,在自己的线程中使用Worker和Superviser。但希望你能帮助我找到更好/更清洁的解决方案。
米蒂亚
答案 0 :(得分:0)
一种方法是对计算进行分块并在计时器事件中进行处理:
所以,如果你当前的算法看起来像
void MyObject::calculate()
{
// data and state
while(processing)
{
///do some chunk of work
}
emit done(result);
}
它将成为
// data and state in fields
void MyObject::calculate()
{
if(!timerId)
timerId = startTimer(0);//timeout of 0 means
//reset state and set data
}
void MyObject::timerEvent(QTimerEvent* event)
{
///do some chunk of work
if(done)
{
emit done(result);
killTimer(timerId);
timerId = 0;
{
}
不需要信号量,因为它都发生在同一个事件循环中。你甚至不需要一个单独的线程,因为事件循环可以继续运行。