Spec-Zone.ru › Qt 5.13

Класс QThread

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

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

Типы публичного доступа

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

Функции публичного доступа

QThread(QObject *parent = nullptr)
виртуальный ~QThread()
QAbstractEventDispatcher * eventDispatcher() const
void exit(int returnCode = 0)
bool isFinished() const
bool isInterruptionRequested() const
bool isRunning() const
int loopLevel() const
QThread::Priority priority() const
void requestInterruption()
void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
void setPriority(QThread::Priority priority)
void setStackSize(uint stackSize)
uint stackSize() const
bool wait(unsigned long time = ULONG_MAX)

Переопределенные функции публичного доступа

виртуальный bool event(QEvent *event) override

Свойства публичного доступа

void quit()
void start(QThread::Priority priority = InheritPriority)
void terminate()

Сигналы

void finished()
void started()

Статические члены публичного доступа

QThread * create(Function &&f, Args &&... args)
QThread * create(Function &&f)
QThread * currentThread()
Qt::HANDLE currentThreadId()
int idealThreadCount()
void msleep(unsigned long msecs)
void sleep(unsigned long secs)
void usleep(unsigned long usecs)
void yieldCurrentThread()

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

int exec()
виртуальный void run()

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

void setTerminationEnabled(bool enabled = true)

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

Объект QThread управляет одним потоком управления в программе. QThreads начинают выполнение в 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() 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, будут выполняться в потоке, который вызвал метод. При наследовании от 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() возвращают идентификаторы текущего потока. Первая возвращает специфичный для платформы идентификатор потока, а вторая — указатель на объект 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 = nullptr)

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

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

[signal] void QThread::finished()

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

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

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

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

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

[slot] void QThread::quit()

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

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

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

[slot] void QThread::start(QThread::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().

[virtual] QThread::~QThread()

Удаляет QThread.

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

[static] QThread *QThread::create(Function &&f, Args &&... args)

Создаёт новый объект QThread, который выполнит функцию f с аргументами args.

Новый поток не запускается — его необходимо запустить явным вызовом start(). Это позволяет подключиться к его сигналам, переместить QObjects в поток, выбрать приоритет нового потока и так далее. Функция f будет вызвана в новом потоке.

Возвращает новый созданный объект QThread.

Примечание: вызывающий код получает владение возвращённым объектом QThread.

Примечание: эта функция доступна только при использовании C++17.

Предупреждение: не вызывайте start() на возвращённом объекте QThread более одного раза; это приведёт к неопределённому поведению.

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

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

[static] QThread *QThread::create(Function &&f)

Создаёт новый объект QThread, который выполнит функцию f.

Новый поток не запускается — его необходимо запустить явным вызовом start(). Это позволяет подключиться к его сигналам, переместить QObjects в поток, выбрать приоритет нового потока и так далее. Функция f будет вызвана в новом потоке.

Возвращает новый созданный объект QThread.

Примечание: вызывающий код получает владение возвращённым объектом QThread.

Предупреждение: не вызывайте start() на возвращённом объекте QThread более одного раза; это приведёт к неопределённому поведению.

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

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

[static] QThread *QThread::currentThread()

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

[static] Qt::HANDLE QThread::currentThreadId()

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

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

END_OF_DOCUMENT_MARKER

Примечание: В Windows эта функция возвращает DWORD (ID потока Windows), возвращаемый функцией Win32 GetCurrentThreadId(), а не псевдо-HANDLE (HANDLE потока Windows), возвращаемый функцией Win32 GetCurrentThread().

[override virtual] bool QThread::event(QEvent *event)

Переопределяет: QObject::event(QEvent *e).

QAbstractEventDispatcher *QThread::eventDispatcher() const

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

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

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

[protected] 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.

[static] 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.

[static] void QThread::msleep(unsigned long msecs)

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

Избегайте использования этой функции, если вам нужно дождаться изменения определённого условия. Вместо этого подключите слот к сигналу, указывающему на изменение, или используйте обработчик событий (см. QObject::event()).

Примечание: Эта функция не гарантирует точности. При высокой нагрузке приложение может спать дольше, чем msecs. Некоторые ОС могут округлять msecs до 10 мс или 15 мс.

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

QThread::Priority QThread::priority() const

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

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

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

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(QThread::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 секунд.

Избегайте использования этой функции, если вам нужно дождаться изменения определённого условия. Вместо этого подключите слот к сигналу, указывающему на изменение, или используйте обработчик событий (см. QObject::event()).

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

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

uint QThread::stackSize() const

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

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

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

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

Избегайте использования этой функции, если вам нужно дождаться изменения определенного условия. Вместо этого подключите слот к сигналу, указывающему на изменение, или используйте обработчик событий (см. QObject::event()).

Примечание: Эта функция не гарантирует точности. При высокой нагрузке приложение может спать дольше, чем usecs. Некоторые операционные системы могут округлять usecs до 10 мс или 15 мс; в Windows оно будет округлено до кратного 1 мс.

См. также 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/qt-5.13/qthread.html

Spec-Zone.ru

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