Применение классов Qt во вторичных потоках

Функция называется потокозащищенной (thread-safe), если она может спокойно вызываться одновременно из нескольких потоков. Если две такие функции вызыва­ются из различных потоков и совместно используют одинаковые данные, результат всегда будет вполне определенным. Это определение можно расширить на класс, и тогда класс будет называться потокозащищенным, если все его функции могут вы­зываться одновременно из различных потоков, не мешая работе друг друга, если они даже работают с одним и тем же объектом.

В Qt потокозащищенными являются классы QMutex, QMutexLocker, QReadWrite­Lock, QReadLocker, QWriteLocker, QSemaphore, QThreadStorage<T>, QWaitCondition и часть программного интерфейса QThread. Кроме того, несколько функций являются пото­козащищенными, в частности QObject::connect(), QObject::disconnect(),QCoreAppli­cation: :postEvent(), QCoreApplication:: removePostedEvent() и QCoreApplication: :re-movePostedEvents().

Большинство классов Qt неграфического интерфейса удовлетворяют менее строгому ограничению: они являются реентерабельными (reentrant). Класс называ­ется реентерабельным, если разные его экземпляры могут одновременно использо­ваться разными потоками. Однако одновременный доступ к одному реентерабельно­му объекту при многопоточной обработке недостаточно надежен и должен конт­ролироваться при помощи мьютекса. Реентерабельность классов отмечается в справочной документации Qt. Обычно любой класс С++, который не использует глобальные переменные (или, другими словами, совместно используемые данные), является реентерабельным.

Класс QOb j ect - реентерабельный, однако не следует забывать о трех ограничениях: • Дочерние объекты QObject должны создаваться их родительским потоком.

В частности, это означает, что созданные во вторичном потоке объекты нельзя создавать с указанием в качестве родительского объекта QThread, потому что этот объект был создан в другом потоке (либо в главном потоке, либо в другом вто­ричном потоке).

• Все объекты QObject, созданные во вторичном потоке, должны быть удалены до удаления соответствующего объекта QThread.

Это можно обеспечить путем создания объектов в стеке функцией QTHRead:: run().

• Объекты QObject должны удаляться в том потоке, в котором они были созданы.


<< назад вперед >>