Проблема с синхронизацией QThreads - PullRequest
0 голосов
/ 01 сентября 2009

Помимо основного потока, у меня есть объект _thinker ThinkerThread, сигнал Finish () которого подключен к слоту основного потока:

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 закончил (), он вызовет autoMove () и покажет обратную связь Но возможно, что неправильная обратная связь предоставлена ​​пользователю, потому что, возможно, загрузка из файла вызывает изменение внутреннего состояния. Это означает, что внутреннее состояние _thinker и внутренние состояния основного потока не совпадают.

  1. _thinker запускается, с состояниями, скажем, s0.
  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 () все еще вызывается и дает обратную связь предыдущего состояния. Я использую Qt Creator 1.2.1 с Qt версии 4.5.2 в Windows.

Спасибо за ваше время.

Редактировать

Это обычный шаг выполнения (когда не вызывается 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 ]

1 голос
/ 30 октября 2009

Как насчет использования целочисленного идентификатора, чтобы определить, какое состояние было вычислено, чтобы увидеть, действительно ли оно все еще действует после завершения вычислений?

0 голосов
/ 01 сентября 2009

Не совсем лучшая практика, но почему бы вам не отметить с помощью bool (используйте мьютексы, если необходимо), что состояние изменилось во время выполнения, и, если это так, просто перезапустите поток в autoMove (не предоставляйте никакой обратной связи ).

Обновление: Я думал что-то вроде:

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

 }

Конечно, если пользователь часто меняет состояние, вы можете никогда не достичь ветки обратной связи: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...