Обмен сообщениями между потоками


Один из важнейших вопросов при многопоточном программировании — это обмен сообщениями. Действительно, если вы, например, в одном потоке создаете растровое изображение и хотели бы переслать его объекту другого потока, то каким образом вы можете это сделать?

Каждый поток может иметь свой собственный цикл событий. Благодаря этому можно осуществлять связь между объектами. Такая связь может производиться двумя способами: при помощи соединения сигналов и слотов или обмена событиями.

Примечание. Если сигнально-слотовое соединение осуществляется между объектами разных потоков, то внутри оно преобразуется в событие.

Использование в потоках собственных циклов обработки событий позволяет снять ограничение, связанное с применением классов, способных работать только в одном цикле событий, и использовать, параллельно, нужное количество объектов этих классов. К таким классам относятся класс QTimer и сетевые классы.

Для того чтобы запустить собственный цикл обработки событий в потоке, нужно поместить вызов метода exec() в методе run(). Цикл обработки событий потока можно завершать посредством слота quit() или метода exit(). Это очень похоже на то, как мы обычно поступаем с объектом приложения в функции main().

Класс QObject реализован так, что обладает близостью к потокам. Каждый объект, произведенный от унаследованного от QObject класса, располагает ссылкой на поток, в котором он был создан. Эту ссылку можно получить вызовом метода QObject::thread(). Потоки осведомляют свои объекты. Благодаря этому каждый объект знает, к какому потоку он принадлежит.

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

Читать далее: Сигнально-слотовые соединения