crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Закрытие потока, как правильно это сделать?
AD
  опции профиля:
сообщение 23.6.2009, 13:57
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Что-то не удается закрыть поток:
/// Класс параллельного потока для чтения в автоматическом режиме параметров
class ReadAutoThread: public QThread
{
Q_OBJECT

protected:
         virtual void run();
};

void ReadAutoThread::run()
{
        connect(imitTsl, SIGNAL(thread_stop()), SLOT(quit()));
/// imitTsl - указатель на главное окно программы и соответственно основной поток

    for(;;)
    {
        /// что-нибудь да делаем.
    }
}


а в главном окне программы есть следующий сигнал:
/// Класс главного окна программы
class ImitatorTSL: public QMainWindow, public Ui::ImitatorTSLClass
{
    Q_OBJECT

signals:
void thread_stop();
}

/// Изменение текущей вкладки
void ImitatorTSL::changeTab(int index)
{
    ////

    if(index != 2 && _curr_page == 2)
        emit thread_stop();
      ////
}


В основной программе в слоте переключения вкладок я имитирую этот сигнал. В чем ошибка, из потока все-равно не выходит. В этот бесконечный цикл все-равно попадает.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 23.6.2009, 14:05
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(AD @ 23.6.2009, 14:57) *
В основной программе в слоте переключения вкладок я имитирую этот сигнал.

И слот на него выполняется тоже в основной программе, если ты не делал thread->moveToThread(thread);

Цитата(AD @ 23.6.2009, 14:57) *
В этот бесконечный цикл все-равно попадает.


В этом бесконечном цикле тогда надо проверять флаг типа if (finished) return;
А в слоте его тогда надо устанавливать. Неужели бесконечный цикл нельзя заменить на exec()? И выполнять задачи в слотах по таймеру или по сигналам из внешнего потока?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 23.6.2009, 14:14
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(SABROG @ 23.6.2009, 15:05) *
В этом бесконечном цикле тогда надо проверять флаг типа if (finished) return;
А в слоте его тогда надо устанавливать. Неужели бесконечный цикл нельзя заменить на exec()? И выполнять задачи в слотах по таймеру или по сигналам из внешнего потока?

А что за флаг? Т.е. в слоте устанавливать его, а в потоке в цикле проверять?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 23.6.2009, 14:19
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(AD @ 23.6.2009, 15:14) *
Цитата(SABROG @ 23.6.2009, 15:05) *
В этом бесконечном цикле тогда надо проверять флаг типа if (finished) return;
А в слоте его тогда надо устанавливать. Неужели бесконечный цикл нельзя заменить на exec()? И выполнять задачи в слотах по таймеру или по сигналам из внешнего потока?

А что за флаг? Т.е. в слоте устанавливать его, а в потоке в цикле проверять?

Ну да, по-старинке объявить некую переменную bool terminate = false. В слоте его выставлять, а в бесконечном цикле проверять. Только тут как обычно 2 косяка возникает - использование sleep(), чтобы не грузить проц бесконечным циклом и возможная долгая пауза перед завершением потока, если опрашиваемое устройство не отвечает долгое время и не дает проверить флаг terminate.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 23.6.2009, 17:32
Сообщение #5


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(AD @ 23.6.2009, 14:57) *
connect(imitTsl, SIGNAL(thread_stop()), SLOT(quit()));

Цитата
void QThread::quit () [slot]

Tells the thread's event loop to exit with return code 0 (success). Equivalent to calling QThread::exit(0).

This function does nothing if the thread does not have an event loop.

See also exit() and QEventLoop.


Смотри
Цитата
void QThread::terminate () [slot]
Сам я никогда этой функцией не пользовался, но вроде, то что надо

P.S. ИМХО. Мне не очень нравится когда коннекты раскидывают по всей программе. Программы становится труднее читать. Зачем он вынесен в run?
На мой взгляд, конекты лучше делать там, где создается экземпляр класса.

Сообщение отредактировал igor_bogomolov - 23.6.2009, 17:36
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 23.6.2009, 18:15
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(igor_bogomolov @ 23.6.2009, 18:32) *
Смотри
Цитата
void QThread::terminate () [slot]

;)
Не самая хорошая функция - аварийное завершение потока, а то и программы!
Цитата
void QThread::terminate () [slot]
Terminates the execution of the thread. The thread may or may not be terminated immediately, depending on the operating systems scheduling policies. Use QThread::wait() after terminate() for synchronous termination.
When the thread is terminated, all threads waiting for the thread to finish will be woken up.
Warning: This function is dangerous and its use is discouraged. The thread can be terminate at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to cleanup after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
Termination can be explicitly enabled or disabled by calling QThread::setTerminationEnabled(). Calling this function while termination is disabled results in the termination being deferred, until termination is re-enabled. See the documentation of QThread::setTerminationEnabled() for more information.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 23.6.2009, 19:02
Сообщение #7


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(AD @ 23.6.2009, 19:15) *
Не самая хорошая функция
На самом деле, даже в документации не рекомендуют ее использовать.
quit тебе тоже не помошник, т.к. нет eventLoop.

Значит совет SABROG-а, остается единственным решением в данном случае.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.6.2009, 20:20
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(AD @ 23.6.2009, 17:57) *
connect(imitTsl, SIGNAL(thread_stop()), SLOT(quit()));

В твоей программе РОДИТЕЛЬ - окно, я думаю в нём создаётся объект потока ДЕТЁНЫШ.

Дак почему ты в детёныше соеденяешь сигнал родителя с самим детёнышем, это откуда такая практика?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 23.6.2009, 23:04
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Litkevich Yuriy @ 23.6.2009, 21:20) *
В твоей программе РОДИТЕЛЬ - окно, я думаю в нём создаётся объект потока ДЕТЁНЫШ.

Дак почему ты в детёныше соеденяешь сигнал родителя с самим детёнышем, это откуда такая практика?

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

Сообщение отредактировал AD - 23.6.2009, 23:05
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.6.2009, 23:19
Сообщение #10


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(AD @ 24.6.2009, 3:04) *
Дак ты сам говорил, что неважно, в каком направлении
направление - не место.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 24.4.2024, 10:09