Spec-Zone.ru › Qt 5.11

Класс QWaitCondition

Класс QWaitCondition предоставляет переменную условия для синхронизации потоков. Подробнее...

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

Примечание: Все функции в этом классе являются безопасными для потоков.

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

QWaitCondition()
~QWaitCondition()
void notify_all()
void notify_one()
bool wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX)
bool wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX)
void wakeAll()
void wakeOne()

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

Класс QWaitCondition предоставляет переменную условия для синхронизации потоков.

QWaitCondition позволяет одному потоку сообщать другим потокам, что какое-то условие выполнено. Один или несколько потоков могут заблокироваться в ожидании, пока QWaitCondition не установит условие с помощью wakeOne() или wakeAll(). Используйте wakeOne(), чтобы разбудить один случайно выбранный поток, или wakeAll(), чтобы разбудить все.

Например, предположим, что у нас есть три задачи, которые должны выполняться всякий раз, когда пользователь нажимает клавишу. Каждая задача может быть разделена на поток, каждый из которых будет иметь тело run() примерно такого вида:

forever {
    mutex.lock();
    keyPressed.wait(&mutex);
    do_something();
    mutex.unlock();
}

Здесь переменная keyPressed является глобальной переменной типа QWaitCondition.

Четвертый поток будет считывать нажатия клавиш и разбуживать три других потока каждый раз, когда он получает нажатие, примерно так:

forever {
    getchar();
    keyPressed.wakeAll();
}

Порядок, в котором будятся три потока, не определен. Кроме того, если некоторые потоки все еще находятся в do_something(), когда нажимается клавиша, они не будут разбужены (поскольку они не ожидают переменной условия), и поэтому задача не будет выполнена для этого нажатия клавиши. Эту проблему можно решить, используя счетчик и QMutex для его защиты. Например, вот новый код для рабочих потоков:

forever {
    mutex.lock();
    keyPressed.wait(&mutex);
    ++count;
    mutex.unlock();

    do_something();

    mutex.lock();
    --count;
    mutex.unlock();
}

Вот код для четвертого потока:

forever {
    getchar();

    mutex.lock();
    // Sleep until there are no busy worker threads
    while (count > 0) {
        mutex.unlock();
        sleep(1);
        mutex.lock();
    }
    keyPressed.wakeAll();
    mutex.unlock();
}

Мьютекс необходим, потому что результаты попыток двух потоков изменить значение одной переменной одновременно непредсказуемы.

Переменные условия — мощный инструмент синхронизации потоков. Пример Wait Conditions Example демонстрирует, как использовать QWaitCondition в качестве альтернативы QSemaphore для управления доступом к кольцевому буферу, который разделяется между производителем и потребителем потоков.

См. также QMutex, QSemaphore, QThread и Wait Conditions Example.

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

QWaitCondition::QWaitCondition()

Конструирует новый объект ожидания условия.

QWaitCondition::~QWaitCondition()

Удаляет объект ожидания условия.

void QWaitCondition::notify_all()

Эта функция предоставлена для совместимости со STL. Она эквивалентна wakeAll().

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

void QWaitCondition::notify_one()

Эта функция предоставлена для совместимости со STL. Она эквивалентна wakeOne().

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

bool QWaitCondition::wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX)

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

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

lockedMutex будет возвращён в то же заблокированное состояние. Эта функция предназначена для обеспечения атомарного перехода от заблокированного состояния к состоянию ожидания.

См. также wakeOne() и wakeAll().

bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX)

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

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

lockedReadWriteLock будет возвращён в то же заблокированное состояние. Эта функция предназначена для обеспечения атомарного перехода от заблокированного состояния к состоянию ожидания.

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

См. также wakeOne() и wakeAll().

void QWaitCondition::wakeAll()

Разбуждает все потоки, ожидающие переменной условия. Порядок, в котором потоки разбуживаются, зависит от политик планирования операционной системы и не может быть контролироваться или предсказываться.

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

void QWaitCondition::wakeOne()

Разбуждает один поток, ожидающий переменной условия. Поток, который будет разбужен, зависит от политик планирования операционной системы и не может быть контролироваться или предсказываться.

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

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

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

Spec-Zone.ru

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