Spec-Zone.ru › Qt 5.14

Класс QThread

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

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

Типы Public

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

Функции Public

QThread(QObject *parent = nullptr)
virtual ~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)

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

virtual bool event(QEvent *event) override

Свойства Public

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

Сигналы

void finished()
void started()

Статические члены Public

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()
virtual void run()

Защищенные статические члены

void setTerminationEnabled(bool enabled = true)

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

Объект 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 будет уведомлять вас через сигнал, когда поток запустится() и завершится(), или вы можете использовать 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(), имя вашей нити будет именем класса runtime-типа вашего объекта нити (например, "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()

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

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

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

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

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

END_OF_DOCUMENT_MARKER

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-библиотеки, эта функция возвращается вызывающей стороне — это обработка событий останавливается.

Ни один QEventLoop больше не будет запускаться в этом потоке, пока не будет повторно вызвано 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.14/qthread.html

Spec-Zone.ru

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