代码之家  ›  专栏  ›  技术社区  ›  Donotalo

同步qthreads时出现问题

  •  0
  • Donotalo  · 技术社区  · 15 年前

    除了主线程,我还有thinker thread对象thinker,其finished()信号连接到主线程的插槽:

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

    slot automove()使thinker初始化并再次运行:

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

    这样,thinker可以继续使用新的数据运行,并通过automove()槽向主线程中的用户提供一些反馈。

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

    假设thinker正在运行,并且用户从文件加载新状态。现在,当thinker finished()时,它将调用automove()并显示反馈。但有可能给用户错误的反馈,因为从文件加载可能会导致内部状态更改。也就是说,思想家的内部状态和主线的内部状态不一样。

    1. _思考者从状态开始,比如说。
    2. 用户从文件中加载另一个状态,比如s1。
    3. _ Thinker完成并执行automove()。

    因此,在步骤3之后,automove()将为状态S0提供反馈,这是不期望的。我要做的是,当用户从文件加载新状态时,停止Thinker的执行。我认为我的设计很差,我想知道在这种情况下的最佳实践。我的加载函数初始化thinker的方式与automove()相同,调用相同的函数(还有另一个函数调用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()只忽略一次?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Macke    15 年前

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

        2
  •  0
  •   Ionut Anghelcovici    15 年前

    不完全是最佳实践,但是为什么不用bool(必要时使用mutexes)标记状态在执行期间发生了更改,如果是这样,只需在automove中重新启动线程(不提供任何反馈)。

    更新: 我在想:

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

    当然,如果用户经常更改状态,您可能永远无法访问provide feedback分支:p