如何实现消费者可以请求新数据的消费者生产者

时间:2013-11-21 22:08:26

标签: c++ qt signals-slots

HY。

我甚至不确定如何为这个问题形成标题。

制片: 我有一个案例,我想在屏幕上显示一些数据,但每次用户与窗口交互时都需要重新计算。对于单击,拖动或滚轮事件,我发送一个请求重新计算的信号。因此,对于旋转(拖动事件),可以发出数十个请求。但是如果数据已经重新计算,procces必须停止并重新启动。重新计算可能需要10毫秒到5秒。然后使用信号量/互斥量我在数据就绪时在鼠标光标上显示一些信息。

消费者: 应该收到重新计算的请求并开始重新计算。还应该停止以前的任何计算。当计算超过解锁互斥锁/信号量时。

我一直在思考和谷歌搜索,但仍然无法找到解决此问题的完美解决方案。你能否指出一些可能适用于这种情况的通用解决方案。

我认为有关QT信号和插槽系统的一些事实与此问题有关: - 执行计算时,eventloop不活动,因此在计算完成之前不会执行插槽 - 一次一个地执行插槽

我的解决方案是在主线程中使用Consumer,在自己的线程中使用Worker和Superviser。但希望你能帮助我找到更好/更清洁的解决方案。

米蒂亚

1 个答案:

答案 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;
    {
}

不需要信号量,因为它都发生在同一个事件循环中。你甚至不需要一个单独的线程,因为事件循环可以继续运行。

相关问题