Во всех приводимых до сих пор примерах наши потоки имеют доступ к одинаковым глобальным переменным. Но для некоторых многопоточных приложений требуется хранить в глобальных переменных неодинаковые данные для разных потоков. Эти переменные часто называют локальной памятью потока (thread-local storage — TLS) или специальными данными потока (thread-specific data — TSD). Мы можем «схитрить» и использовать отображение, в качестве ключей которого применяются идентификаторы потоков (возвращаемые функцией
Обычно класс
01 QThreadStorage
02 void insertIntoCache(int id, double value)
03 {
04 if (!cache.hasLocalData)
05 cache.setLocalData(new QHash
06 cache.localData->insert(id, value);
07 }
08 void removeFromCache(int id)
09 {
10 if (cache.hasLocalData)
11 cache.localData->remove(id);
12 }
Переменная
Кроме кэширования класс
Взаимодействие с главным потоком
При запуске приложения Qt работает только один поток — главный. Только этот поток может создать объект
Главный поток может запускать новые потоки, создавая объекты подкласса
Для связи вторичного потока с главным потоком необходимо использовать межпоточные соединения сигнал—слот. Обычно механизм сигналов и слотов работает синхронно, т.е. связанный с сигналом слот вызывается сразу после генерации сигнала, используя прямой вызов функции.
Однако когда вы связываете объекты, «живущие» в других потоках, механизм взаимодействия сигналов и слотов становится асинхронным. (Такое поведение можно изменить с помощью пятого параметра функции
Для иллюстрации работы соединений сигнал—слот с разными потоками мы рассмотрим программный код приложения Image Pro — процессора изображений, обеспечивающего базовые возможности и позволяющего пользователю поворачивать, изменять размер и цвет изображения. В данном приложении используется один вторичный поток для выполнения операций над изображениями без блокировки цикла обработки событий. Это имеет существенное значение при обработке изображений очень большого размера. Вторичный поток имеет список выполняемых задач или «транзакций», и он генерирует события для главного окна, чтобы сообщать о том, как идет процесс их выполнения.
01 ImageWindow::ImageWindow
02 {
03 imageLabel = new QLabel;
04 imageLabel->setBackgroundRole(QPalette::Dark);
05 imageLabel->setAutoFillBackground(true);
06 imageLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
07 setCentralWidget(imageLabel);