Spec-Zone.ru › Qt 5.12

Класс 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
  • 32 открытые функции унаследованы от QObject

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

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

Сигналы

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

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

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)
const QMetaObject staticMetaObject
void usleep(unsigned long usecs)
void yieldCurrentThread()
  • 10 статических открытых членов унаследованы от QObject

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

int exec()
виртуальный 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() 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 уведомит вас о запуске и завершении потока с помощью сигнала started() и finished() или вы можете использовать isFinished() и isRunning() для запроса состояния потока.

Вы можете остановить поток, вызвав exit() или quit(). В крайних случаях вы можете принудительно terminate() работающий поток. Однако это опасно и не рекомендуется. Пожалуйста, ознакомьтесь с документацией для 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(), имя, присвоенное вашему потоку, будет именем класса runtime-типа вашего объекта потока (например, "RenderThread" в случае примера Mandelbrot, так как это имя подкласса QThread). Обратите внимание, что в настоящее время это недоступно в релизных сборках на Windows.

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

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

перечисление 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().

[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()

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

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

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

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

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

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.

[signal] void QThread::finished()

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

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

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

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

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

[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().

[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(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 ложь, завершение отключено. Будущие вызовы QThread::terminate() вернутся сразу без эффекта. Вместо этого завершение откладывается до включения завершения.

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

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

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

Заставляет текущий поток спать в течение secs секунд.

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

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

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

uint QThread::stackSize() const

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

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

[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().

[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.12/qthread.html

Spec-Zone.ru

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