Russian Qt Forum
Ноябрь 23, 2024, 06:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Завершение работы вторичного потока  (Прочитано 5920 раз)
Zerkin
Чайник
*
Offline Offline

Сообщений: 98


Просмотр профиля
« : Март 23, 2012, 11:57 »

Доброго времен суток. Вопрос следующий (может показаться тривиальным, но опыта в многопоточном программировании имею крайне мало, так что не обессудьте) :

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

Далее, для наглядности, код метода run класса вторичного потока.

Код:
void	ModeThread::run()
{
_mutex.lock();
State state = _state;
_mutex.unlock();
while (state != STOPPED)
{
_mutex.lock();
state = _state;
_mutex.unlock();
if (state == ANALYSIS)
{
UIProgressObserverObject->progress(_state, _inputFile->fileName()); //уведомление графики
Analyzer::start(_inputFile, UIResultObserverObject, _stm_type, UIProgressObserverObject);
_mutex.lock();
_state = WAITING;
_mutex.unlock();
UIProgressObserverObject->progress(_state, _inputFile->fileName());  //уведомление графики
}
else if (state == HANDLE)
{
Handler::start();
_mutex.lock();
_state = WAITING;
_mutex.unlock();
}
else if (state == WAITING)
{
_mutex.lock();
state = _state;
_waitCondition.wait(&_mutex);
_mutex.unlock();
}
}
}

Нужно прервать работу этого потока по желанию пользователя (он тыркает некоторую кнопку - поток завершается). Реализовал еще один обзервер для этих целей, всё хорошо. Но не учел тот факт что у меня состояние не изменится пока данный момент не выполниться:

Код:
Analyzer::start(_inputFile, UIResultObserverObject, _stm_type, UIProgressObserverObject);

или этот:

Код:
Handler::start();

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

Заранее спасибо.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Март 23, 2012, 12:19 »

Код
C++ (Qt)
void ModeThread::run( void )
{
 while (true) {
  _mutex.lock();
  _waitCondition.wait(&_mutex);
  _mutex.unlock();
  switch (_state)
  {
    case STOPPED:
      return;
 
    case ANALYSIS:
      ...
      break;
 
    case HANDLE:
...
       break;
   }
   _state = WAITING;
  }
}
 
« Последнее редактирование: Март 23, 2012, 12:23 от Igors » Записан
Zerkin
Чайник
*
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #2 : Март 26, 2012, 10:01 »

Ну, я так понимаю, что в любом случае, когда я добавлю вызов функции вот в этом моменте:

Код:
 case ANALYSIS:
       ...
       break;

ничего не изменится, пока она не выполнится состояние не изменить - поток не завершить, кроме как терминейтом? Можно каких-то дополнительных комментариев, если не сложно.
Записан
mutineer
Гость
« Ответ #3 : Март 26, 2012, 10:09 »

в середине выполнения кода потока, без дополнительных проверок, прервать его можно только через terminate
Записан
Zerkin
Чайник
*
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #4 : Март 26, 2012, 10:21 »

Но это не желательное действие, как я понимаю?
Записан
mutineer
Гость
« Ответ #5 : Март 26, 2012, 10:23 »

ага, нежелательное. Особенно при наличии мьютексов в коде потока
Записан
Zerkin
Чайник
*
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #6 : Март 26, 2012, 10:54 »

эх, получается кроме как вставлять непосредственно код анализа в этот момент у меня вариантов нету?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Март 26, 2012, 11:49 »

эх, получается кроме как вставлять непосредственно код анализа в этот момент у меня вариантов нету?
Может даже не в этот, а с "каким-то интервалом" проверять флажок отмены и выходить из run (и/или сначала из вложенных в него ф-ций). Это нормально и этот способ практически единственный (др сложны или ненадежны)
Записан
Zerkin
Чайник
*
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #8 : Март 26, 2012, 12:10 »

В общем, идею понял, но мне придется многое на других уровнях изменять. Не стану использовать ни терминейт, ни что-то еще. Пока функциональность обеспечена удовлетворительная, пусть поток висит, всё равно завершится,  так что на данном этапе заниматься этим не стану, попозже или в другой версии, но в любом случае спасибо за помощь!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.08 секунд. Запросов: 23.