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

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

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Как завершить поток таймера?  (Прочитано 19763 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #30 : Декабрь 13, 2017, 09:22 »

Цитировать
По-моему это уже обсуждали http://www.prog.org.ru/index.php?topic=31557.msg233459#msg233459 или что-то другое имеется в виду?

Там в примере неправильно использован концепт. В концепте deleteThread() должен вызываться только по сигналам finished() и никак иначе (иначе можно и Машку за ляшку и козу на возу  Улыбающийся ).
« Последнее редактирование: Декабрь 13, 2017, 09:25 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #31 : Декабрь 13, 2017, 12:02 »

Ну то бишь верно будет так:

Код
C++ (Qt)
   QThread thread;
   Worker * worker = new Worker;
   worker->moveToThread( &thread );
   QObject::connect( &thread, SIGNAL( finished() ), worker, SLOT( deleteLater() ) );
   thread.start();
...
   thread.quit();
   thread.wait();
 

Это будет работать, так как finished() вызывается в потоке, в котором функционирует worker.
При этом важно, чтобы connect был выполнен по умолчанию (с опцией Qt::AutoConnection).

При этом wait() обязателен до удаления экземпляра thread, иначе снова может получиться)

Цитировать
QThread: Destroyed while thread is still running

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #32 : Декабрь 13, 2017, 12:36 »

thread существует в контексте нити в которой он создавался, worker перемещается в контекст нити, которую создаст thread при запуске.
Если был автоматический коннект, то при генерации сигнала будет использоваться очередь рабочей нитки, которая к моменту finished будет уже остановлена и воркер разрушен не будет. Улыбающийся
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #33 : Декабрь 13, 2017, 13:33 »

Происходит примерно следующее (Qt 5.9)

Случай Qt::AutoConnection определяет в runtime каким способом вызывать слот

Код
C++ (Qt)
...
           if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
               || (c->connectionType == Qt::QueuedConnection)) {
...
 

Слот deleteLater() помещает в очередь событие QDeferredDeleteEvent

Код
C++ (Qt)
   QCoreApplication::postEvent(this, new QDeferredDeleteEvent());
 

А QThread уже после вызова слота специальным способом обрабатывает оставшиеся сообщения

Код
C++ (Qt)
...
   emit thr->finished(QThread::QPrivateSignal());
   QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
...
 

Собственно специальная заплата самого Qt.
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


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