2009-09-01 84 views
0

除了主线程,我已经ThinkerThread对象_thinker其成品()信号被连接到主线程的槽:问题同步QThreads

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

槽汽车移动()导致_thinker初始化并再次运行:

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

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

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

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

  1. _thinker开始,状态说s0。
  2. 用户从文件加载另一个状态,比如说s1。
  3. _thinker完成并执行autoMove()。

因此,在步骤3之后,autoMove()会给出状态s0的反馈,这是不期望的。我想要做的是在用户从文件加载新状态时停止执行_thinker。我认为我的设计很差,我想知道这种情况下的最佳做法。我的加载函数以与autoMove()相同的方式初始化_thinker,调用相同的函数(还有另一个函数调用_thinker.setState()和start())。

现在我已经做了在负载下()函数:

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

这并不能完全消除的问题,那就是,汽车移动()仍称并给出了以前的状态的反馈。我在Windows中使用Qt Creator 1.2.1和Qt 4.5.2版本。

谢谢你的时间。

编辑

这是通常的执行步骤(当负载()不被调用):

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

当负载()被调用:

_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()应该忽略只有一次?

回答

1

有关使用如何整数ID来确定哪个状态已经被计算,看看它在计算完成时是否仍然有效?

0

不完全是最佳实践,但为什么不用bool标记(使用互斥体,如果必须的话)状态在执行过程中发生了变化,如果是这样,只需重新启动autoMove中的线程(不提供任何反馈)。

更新: 我的想法是这样的:

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

} 

当然,如果用户改变状态的时候,你可能永远达不到的提供反馈支路:P

+0

这是通常的执行步骤(不调用load()时): _thinker.setState(); _thinker.start(); //当_思考完成时() autoMove(); > _thinker.setState(); > _thinker.start(); load()被调用时: _thinker.setState(); _thinker.start(); load(); > _thinker.setState(); > _thinker.start(); //当_思考完成时() autoMove(); //这是以前的反馈 //或当前状态 > _thinker.setState(); > _thinker.start(); 请注意,load()会导致_thinker重新启动。现在,在哪里布尔检查,以便autoMove()应该忽略只有一次? – Donotalo

+0

哦,格式化分手了。我将其重新发布在原始帖子中。 – Donotalo