MyTetra Share
Делитесь знаниями!
Последовательность переноса объекта в отдельный поток для Qt5
Время создания: 14.04.2020 10:28
Автор: xintrea
Текстовые метки: qt, qt5, QThread, c++, объект, перенос, поток, тред, параллельность, многопоточное программирование
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Многопоточность
Запись: xintrea/mytetra_syncro/master/base/1586849301cevdlkmh7k/text.html на raw.github.com

Перенос объекта Qt в отдельный поток


Правильный перенос объекта Qt в отдельный поток происходит следующим образом:


1. Создать поток QThread.


2. Выполнить метод moveToThread() для нужного объекта, указав ему созданный на этапе 1 поток. При перемещении в тред надо учитывать, что в перемещаемом объекте не должен быть установлен parent.


3. Настроить сигнал-слотовые соединения (connect) для перемещенного объекта. Для того, чтобы вызовы слотов происходили корректно из других потоков, при настройке connect() надо указывать тип соединения Qt::QueuedConnection.


4. Старт потока через метод start(). Данный метод можно вызывать и после шага 2, работать тоже будет без проблем.


5. Если в объекте используются таймеры QTimer, их старт надо навесить либо на слот обработки старта потока, либо делать запуск в уже перенесенном в поток объекте. Таймеры не работают, если они были запущены, а потом объект был перенесен в другой поток.



Выполнение кода


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


Чтобы вызов слота был "отвязан" от вызывающего потока, и слот объекта выполнялся в потоке, в который объект был перемещен, установку сигнал-слотового соединения нужно делать с флагом Qt::QueuedConnection, как это было описано выше. В этом случае запуск слота происходит в потоке объекта, которому принадлежит слот. Для запуска слота, Qt вначале размещает вызов в очередь основного цикла приложения, и сам запуск слота происходит при обработке основного цикла приложения.


В принципе, данные в выполняемый поток (и из него) можно передавать не сигнал-слотами, а другой стратегией. Например, можно установить переменные-члены до вызова метода start (). После запуска рабочего потока, основной поток не должен манипулировать данными рабочего потока. Когда рабочий поток завершается, основной поток снова может получить доступ к данным. Это удобная стратегия для передачи параметров до запуска потока и сбора результатов после его завершения, но она не сработает в случае, если нужно передавать-палучать данные во время работы потока.



Завершение работы потока


Завершать работу потока можно примерно следующим кодом:



myThread->quit();

if( !myThread->wait(2000) )

{

myThread->terminate();

}

Так же в этом разделе:
 
MyTetra Share v.0.65
Яндекс индекс цитирования