Spec-Zone.ru › Qt 5.6

Класс QThread

Класс QThread предоставляет платформенно-независимый способ управления потоками. Подробнее...

Заголовок: #include <QThread>
qmake: QT += core
Наследует: QObject
  • Список всех членов, включая унаследованные

Открытые типы

Перечисление Priority { IdlePriority, LowestPriority, LowPriority, NormalPriority, ..., InheritPriority }

Открытые функции

QThread(QObject *parent = Q_NULLPTR)
~QThread()
QAbstractEventDispatcher * eventDispatcher() const
void exit(int returnCode = 0)
bool isFinished() const
bool isInterruptionRequested() const
bool isRunning() const
int loopLevel() const
Priority priority() const
void requestInterruption()
void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
void setPriority(Priority priority)
void setStackSize(uint stackSize)
uint stackSize() const
bool wait(unsigned long time = ULONG_MAX)

Переопределённые открытые функции

virtual bool event(QEvent *event)
  • 31 открытая функция унаследованная от QObject

Открытые слоты

void quit()
void start(Priority priority = InheritPriority)
void terminate()
  • 1 открытый слот унаследованный от QObject

Сигналы

void finished()
void started()
  • 2 сигнала унаследованных от QObject

Статические открытые члены

QThread * currentThread()
Qt::HANDLE currentThreadId()
int idealThreadCount()
void msleep(unsigned long msecs)
void sleep(unsigned long secs)
void usleep(unsigned long usecs)
void yieldCurrentThread()
  • 11 статических открытых членов унаследованных от QObject

Защищённые функции

int exec()
virtual void run()
  • 9 защищённых функций унаследованных от QObject

Статические защищённые члены

void setTerminationEnabled(bool enabled = true)

Дополнительные унаследованные члены

  • 1 свойство унаследованное от QObject

Подробное описание

Класс QThread предоставляет платформенно-независимый способ управления потоками.

Объект QThread управляет одним потоком управления в программе. Потоки QThread начинают выполнение в run(). По умолчанию, run() запускает цикл событий, вызывая exec(), и выполняет цикл событий Qt внутри потока.

Вы можете использовать объекты-рабочие, перемещая их в поток с помощью QObject::moveToThread().

class Worker : public QObject
{
    Q_OBJECT

public slots:
    void doWork(const QString &parameter) {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        emit resultReady(result);
    }

signals:
    void resultReady(const QString &result);
};

class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    Controller() {
        Worker *worker = new Worker;
        worker->moveToThread(&workerThread);
        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
        connect(this, &Controller::operate, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        workerThread.start();
    }
    ~Controller() {
        workerThread.quit();
        workerThread.wait();
    }
public slots:
    void handleResults(const QString &);
signals:
    void operate(const QString &);
};

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

Другой способ запустить код в отдельном потоке — это создание подкласса QThread и переопределение run(). Например:

class WorkerThread : public QThread
{
    Q_OBJECT
    void run() Q_DECL_OVERRIDE {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &s);
};

void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->start();
}

В этом примере поток завершится после возврата из функции run. В потоке не будет выполняться цикл событий, если вы не вызовете exec().

Важно помнить, что экземпляр QThread расположен в старом потоке, который его инициализировал, а не в новом потоке, который вызывает run(). Это означает, что все очереди слотов QThread будут выполняться в старом потоке. Таким образом, разработчик, который хочет вызвать слоты в новом потоке, должен использовать подход с объектом-рабочим; новые слоты не должны быть реализованы непосредственно в подклассе QThread.

При наследовании от QThread, имейте в виду, что конструктор выполняется в старом потоке, а run() выполняется в новом потоке. Если к члену переменной обращаются из обеих функций, то переменная обращается из двух разных потоков. Проверьте, безопасно ли это делать.

Примечание: Необходимо соблюдать осторожность при взаимодействии с объектами в разных потоках. Подробности см. в разделе Синхронизация потоков.

Управление потоками

QThread уведомит вас о том, что поток был запущен() и завершён() с помощью сигнала, или вы можете использовать isFinished() и isRunning() для запроса состояния потока.

Вы можете остановить поток, вызвав exit() или quit(). В крайних случаях вы можете принудительно прервать выполняющийся поток. Однако это опасно и не рекомендуется. Подробную информацию см. в документации для terminate() и setTerminationEnabled().

Начиная с Qt 4.8, можно освободить объекты, живущие в потоке, который только что завершился, подключив сигнал finished() к QObject::deleteLater().

Используйте wait(), чтобы заблокировать вызывающий поток до завершения выполнения другого потока (или до истечения заданного времени).

QThread также предоставляет статические, платформенно-независимые функции сна: sleep(), msleep() и usleep() соответственно обеспечивают разрешение по секундам, миллисекундам и микросекундам. Эти функции были сделаны общедоступными в Qt 5.0.

Примечание: wait() и sleep() функции, как правило, не нужны, так как Qt — фреймворк на основе событий. Вместо wait() рассмотрите прослушивание сигнала finished(). Вместо функций sleep() рассмотрите использование QTimer.

Статические функции currentThreadId() и currentThread() возвращают идентификаторы текущего потока. Первая возвращает платформенно-зависимый ID потока; вторая возвращает указатель на QThread.

Чтобы выбрать имя для вашего потока (как идентифицируется командой ps -L на Linux, например), вы можете вызвать setObjectName() перед запуском потока. Если вы не вызываете setObjectName(), имя, присвоенное потоку, будет именем класса типа вашего объекта потока во время выполнения (например, "RenderThread" в случае примера Mandelbrot, так как это имя подкласса QThread). Обратите внимание, что в релизных сборках на Windows это в настоящее время недоступно.

См. также Поддержка потоков в Qt, QThreadStorage, Синхронизация потоков, Пример Mandelbrot, Пример с семафорами и Пример с условиями ожидания.

Документация по типам членов

enum QThread::Priority

Этот тип перечисления указывает, как операционная система должна планировать вновь созданные потоки.

Постоянная Значение Описание
QThread::IdlePriority 0 планируется только тогда, когда другие потоки не работают.
QThread::LowestPriority 1 планируется реже, чем LowPriority.
QThread::LowPriority 2 планируется реже, чем NormalPriority.
QThread::NormalPriority 3 установленный по умолчанию приоритет операционной системы.
QThread::HighPriority 4 планируется чаще, чем NormalPriority.
QThread::HighestPriority 5 планируется чаще, чем HighPriority.
QThread::TimeCriticalPriority 6 планируется как можно чаще.
QThread::InheritPriority 7 используется тот же приоритет, что и у создающего потока. Это значение по умолчанию.

Документация по функциям-членам

QThread::QThread(QObject *parent = Q_NULLPTR)

Создает новый QThread для управления новым потоком. parent получает владение QThread. Поток не начнет выполнение до вызова start().

См. также start().

QThread::~QThread()

Удаляет QThread.

Обратите внимание, что удаление объекта QThread не остановит выполнение управляемого им потока. Удаление работающего QThread (т.е. isFinished() возвращает false) вероятно приведет к аварийному завершению программы. Дождитесь сигнала finished() перед удалением QThread.

QThread *QThread::currentThread()

Возвращает указатель на QThread, который управляет текущим потоком.

Qt::HANDLE QThread::currentThreadId()

Возвращает дескриптор потока текущего выполняемого потока.

Предупреждение: Дескриптор, возвращаемый этой функцией, используется для внутренних целей и не должен использоваться в коде приложения.

Предупреждение: В Windows возвращаемое значение является псевдо-дескриптором для текущего потока. Его нельзя использовать для числового сравнения. Т.е., эта функция возвращает DWORD (ID потока Windows), возвращаемый функцией Win32 getCurrentThreadId(), а не HANDLE (HANDLE потока Windows), возвращаемый функцией Win32 getCurrentThread().

bool QThread::event(QEvent *event)

Переопределено из QObject::event().

QAbstractEventDispatcher *QThread::eventDispatcher() const

Возвращает указатель на объект диспетчера событий для потока. Если для потока нет диспетчера событий, эта функция возвращает 0.

Эта функция была добавлена в Qt 5.0.

См. также setEventDispatcher().

int QThread::exec()

Входит в цикл обработки событий и ожидает вызова exit(), возвращая значение, переданное в exit(). Возвращаемое значение равно 0, если exit() вызывается через quit().

Эта функция предназначена для вызова внутри run(). Для запуска обработки событий необходимо вызвать эту функцию.

См. также quit() и exit().

void QThread::exit(int returnCode = 0)

Уведомляет цикл обработки событий потока о выходе с кодом возврата.

После вызова этой функции поток покидает цикл обработки событий и возвращается из вызова QEventLoop::exec(). Функция QEventLoop::exec() возвращает returnCode.

По соглашению, returnCode со значением 0 означает успех, любое ненулевое значение указывает на ошибку.

Обратите внимание, что в отличие от одноименной функции C-библиотеки, эта функция действительно возвращается вызывающей стороне — останавливается обработка событий.

В этом потоке больше не будут запускаться QEventLoops до тех пор, пока снова не будет вызван QThread::exec(). Если цикл событий в QThread::exec() не запущен, то следующий вызов QThread::exec() также вернётся сразу.

См. также quit() и QEventLoop.

void QThread::finished()

Этот сигнал испускается из ассоциированного потока непосредственно перед завершением его выполнения.

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

Примечание: Если ассоциированный поток был завершен с помощью terminate(), то от какого потока испускается этот сигнал — неопределённо.

Примечание: Это частный сигнал. Он может использоваться в подключениях сигналов, но не может быть испущен пользователем.

См. также started().

int QThread::idealThreadCount()

Возвращает идеальное количество потоков, которые могут быть запущены на системе. Это делается путём запроса количества процессорных ядер, как физических, так и логических, в системе. Эта функция возвращает -1, если количество процессорных ядер не удалось определить.

bool QThread::isFinished() const

Возвращает true, если поток завершён; в противном случае возвращает false.

См. также isRunning().

bool QThread::isInterruptionRequested() const

Возвращает true, если задача, выполняющаяся в этом потоке, должна быть остановлена. Запрос прерывания может быть выполнен с помощью requestInterruption().

Эта функция может быть использована для чистой приостановки задач с длительным выполнением. Безопасно никогда не проверять и не действовать на возвращаемое этой функцией значение, однако рекомендуется делать это регулярно в функциях с длительным выполнением. Следите за тем, чтобы не вызывать её слишком часто, чтобы сохранить низкую нагрузку.

void long_task() {
     forever {
        if ( QThread::currentThread()->isInterruptionRequested() ) {
            return;
        }
    }
}

Эта функция была добавлена в Qt 5.2.

См. также currentThread() и requestInterruption().

bool QThread::isRunning() const

Возвращает true, если поток запущен; в противном случае возвращает false.

См. также isFinished().

int QThread::loopLevel() const

Возвращает текущий уровень цикла обработки событий для потока.

Примечание: Это можно вызвать только внутри самого потока, т.е. когда это текущий поток.

Эта функция была добавлена в Qt 5.5.

void QThread::msleep(unsigned long msecs)

Принудительно останавливает текущий поток на msecs миллисекунд.

См. также sleep() и usleep().

Priority QThread::priority() const

Возвращает приоритет запущенного потока. Если поток не запущен, эта функция возвращает InheritPriority.

Эта функция была добавлена в Qt 4.1.

См. также Priority, setPriority() и start().

[slot] void QThread::quit()

Уведомляет цикл событий потока об окончании работы с кодом возврата 0 (успех). Эквивалентно вызову QThread::exit(0).

Эта функция ничего не делает, если у потока нет цикла событий.

См. также exit() и QEventLoop.

void QThread::requestInterruption()

Запрашивает прерывание потока. Это запрос, и код, выполняющийся в потоке, сам решает, как и нужно ли реагировать на такой запрос. Эта функция не останавливает ни один цикл событий, выполняющийся в потоке, и не завершает его каким-либо образом.

Эта функция была добавлена в Qt 5.2.

См. также isInterruptionRequested().

[virtual protected] void QThread::run()

Точка входа для потока. После вызова start() новый поток вызывает эту функцию. По умолчанию она просто вызывает exec().

Вы можете переопределить эту функцию для более сложного управления потоками. Возврат из этой функции завершит выполнение потока.

См. также start() и wait().

void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)

Устанавливает диспетчер событий для потока в eventDispatcher. Это возможно только до тех пор, пока для потока еще нет установленного диспетчера событий. То есть, до запуска потока с помощью start() или, в случае основного потока, до создания экземпляра QCoreApplication. Этот метод принимает владение объектом.

Эта функция была добавлена в Qt 5.0.

См. также eventDispatcher().

void QThread::setPriority(Priority priority)

Эта функция устанавливает priority для запущенного потока. Если поток не запущен, эта функция ничего не делает и возвращается немедленно. Используйте start(), чтобы запустить поток с определенным приоритетом.

Аргумент priority может принимать любое значение в перечислении QThread::Priority, кроме InheritPriorty.

Эффект параметра priority зависит от политики планирования операционной системы. В частности, priority будет игнорироваться на системах, не поддерживающих приоритеты потоков (например, на Linux, см. http://linux.die.net/man/2/sched_setscheduler для получения дополнительных сведений).

Эта функция была добавлена в Qt 4.1.

См. также Priority, priority() и start().

void QThread::setStackSize(uint stackSize)

Устанавливает максимальный размер стека для потока в stackSize. Если stackSize больше нуля, максимальный размер стека устанавливается в stackSize байтов, в противном случае максимальный размер стека автоматически определяется операционной системой.

Предупреждение: Большинство операционных систем устанавливают минимальные и максимальные ограничения на размеры стека потока. Поток не сможет запуститься, если размер стека выходит за эти пределы.

См. также stackSize().

[static protected] void QThread::setTerminationEnabled(bool enabled = true)

Включает или выключает завершение текущего потока в зависимости от параметра enabled. Поток должен был быть запущен с помощью QThread.

Когда enabled равно false, завершение отключено. Будущие вызовы QThread::terminate() вернутся немедленно без эффекта. Вместо этого завершение откладывается до включения завершения.

Когда enabled равно true, завершение включено. Будущие вызовы QThread::terminate() завершат поток обычным способом. Если завершение было отложено (т.е. QThread::terminate() был вызван с отключенным завершением), эта функция завершит вызывающий поток немедленно. Обратите внимание, что в этом случае функция не вернётся.

См. также terminate().

[static] void QThread::sleep(unsigned long secs)

Принудительно останавливает текущий поток на secs секунд.

См. также msleep() и usleep().

uint QThread::stackSize() const

Возвращает максимальный размер стека для потока (если он был установлен с помощью setStackSize()); в противном случае возвращает ноль.

См. также setStackSize().

[slot] void QThread::start(Priority priority = InheritPriority)

Начинает выполнение потока, вызывая run(). Операционная система будет планировать поток в соответствии с параметром priority. Если поток уже запущен, эта функция ничего не делает.

Эффект параметра priority зависит от политики планирования операционной системы. В частности, priority будет игнорироваться на системах, не поддерживающих приоритеты потоков (например, на Linux, см. документацию к sched_setscheduler для получения дополнительных сведений).

См. также run() и terminate().

[signal] void QThread::started()

Этот сигнал испускается из связанного потока при его запуске, до вызова функции run().

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

См. также finished().

[slot] void QThread::terminate()

Завершает выполнение потока. Поток может быть завершен немедленно или нет, в зависимости от политики планирования операционной системы. Используйте QThread::wait() после terminate(), чтобы быть уверенным.

Когда поток завершен, все потоки, ожидающие завершения потока, будут разбужены.

Предупреждение: Эта функция небезопасна, и её использование не рекомендуется. Поток может быть завершен в любой точке своего пути кода. Потоки могут быть завершены во время изменения данных. Поток не имеет возможности очистить за собой, разблокировать любые захваченные мьютексы и т.д. Короче говоря, используйте эту функцию только если это абсолютно необходимо.

Завершение может быть явно включено или выключено путём вызова QThread::setTerminationEnabled(). Вызов этой функции, когда завершение отключено, приводит к отложению завершения до повторного включения. См. документацию к QThread::setTerminationEnabled() для получения дополнительной информации.

См. также setTerminationEnabled().

[static] void QThread::usleep(unsigned long usecs)

Принудительно останавливает текущий поток на usecs микросекунд.

См. также sleep() и msleep().

bool QThread::wait(unsigned long time = ULONG_MAX)

Задерживает поток, пока не будет выполнено одно из следующих условий:

  • Поток, связанный с этим объектом QThread, завершил выполнение (т.е. когда он возвращается из run()). Эта функция вернёт true, если поток завершился. Она также вернёт true, если поток ещё не был запущен.
  • Прошло time миллисекунд. Если time равно ULONG_MAX (значение по умолчанию), ожидание никогда не истечёт (поток должен вернуться из run()). Эта функция вернёт false, если ожидание истекло.

Это обеспечивает функциональность, аналогичную функции POSIX pthread_join().

См. также sleep() и terminate().

[static] void QThread::yieldCurrentThread()

Уступает выполнение текущего потока другому исполняемому потоку, если таковой имеется. Обратите внимание, что операционная система решает, в какой поток переключиться.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.6/qthread.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API