问题同步QThreads

时间:2009-09-01 14:04:24

标签: c++ multithreading qt

除主线程外,我还有ThinkerThread对象_thinker,其finished()信号连接到主线程的插槽:

connect(&_thinker, SIGNAL(finished()), this, SLOT(autoMove()));

插槽autoMove()会导致_thinker初始化并再次运行:

_thinker.setState(/* set internal variables to run properly */);
_thinker.start();

这样_thinker可以继续使用新数据运行,并使用autoMove()插槽在主线程中向用户提供一些反馈。

问题是当用户希望为_thinker加载新状态时(可能来自文件或其他一些菜单操作),我无法同步_thinker的两种状态。

假设_thinker正在运行,并且用户从文件加载新状态。现在,当_thinker finish()时,它将调用autoMove()并显示反馈。但是可能会向用户提供错误的反馈,因为可能从文件加载会导致内部状态发生变化。这意味着,_thinker的内部状态和主线程的内部状态不一样。

  1. _thinker开始,各州说,s0。
  2. 用户从文件加载另一个状态,比如s1。
  3. _thinker完成并且autoMove()执行。
  4. 因此,在步骤3之后,autoMove()将为状态s0提供反馈,这是不期望的。我想要做的是当用户从文件加载新状态时停止执行_thinker。我认为我的设计很差,我想知道这种情况下的最佳做法。我的加载函数以与autoMove()相同的方式初始化_thinker,调用相同的函数(还有另一个函数调用_thinker.setState()和start())。

    现在我在load()函数中完成了以下操作:

    disconnect(&_thinker, SIGNAL(finished()), this, SLOT(autoMove()));
    _thinker.terminate();
    _thinker.wait();
    connect(&_thinker, SIGNAL(finished()), this, SLOT(autoMove()));
    

    这并不能完全消除这个问题,也就是说,仍然会调用autoMove()并给出以前状态的反馈。我在Windows中使用Qt Creator 1.2.1和Qt版本4.5.2。

    感谢您的时间。

    修改

    这是通常的执行步骤(当没有调用load()时):

    _thinker.setState();
    _thinker.start();
    //when _thinker finished()
    autoMove();
        > _thinker.setState();
        > _thinker.start();
    

    调用load()时:

    _thinker.setState();
    _thinker.start();
    load();
        > _thinker.setState();
        > _thinker.start();
    //when _thinker finished()
    autoMove(); // this is the feedback for previous or current state
        > _thinker.setState();
        > _thinker.start();
    

    注意,load()会导致_thinker重启。现在,在哪里放置一个布尔检查,以便autoMove()应该忽略ONLY ONCE?

2 个答案:

答案 0 :(得分:1)

如何使用整数id来确定计算了哪个状态,看看它在计算结束时是否仍然有效?

答案 1 :(得分:0)

不完全是最佳做法,但为什么不用bool(如果需要请使用互斥锁)标记执行期间状态已更改,如果是,则只需在autoMove中重新启动线程(不提供任何反馈) )。

更新: 我想的是:

autoMove() 
{ 
    .... 
    if (!_thinker.stateChanged())  
    {
       // provide feedback
    } 
    //restart _thinker -> on restart _thinker.isStateChanged = false;

 }

当然,如果用户经常更改状态,您可能永远不会到达提供反馈分支:P