除主线程外,我还有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的内部状态和主线程的内部状态不一样。
因此,在步骤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?
答案 0 :(得分:1)
如何使用整数id来确定计算了哪个状态,看看它在计算结束时是否仍然有效?
答案 1 :(得分:0)
不完全是最佳做法,但为什么不用bool(如果需要请使用互斥锁)标记执行期间状态已更改,如果是,则只需在autoMove中重新启动线程(不提供任何反馈) )。
更新: 我想的是:
autoMove()
{
....
if (!_thinker.stateChanged())
{
// provide feedback
}
//restart _thinker -> on restart _thinker.isStateChanged = false;
}
当然,如果用户经常更改状态,您可能永远不会到达提供反馈分支:P