Spec-Zone.ru › Qt 5.9

Класс 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()

Создает новый объект wait condition.

QWaitCondition::~QWaitCondition()

Уничтожает объект wait condition.

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 и ожидает события wait condition. 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 и ожидает события wait condition. lockedReadWriteLock должен быть изначально заблокирован вызывающим потоком. Если lockedReadWriteLock не заблокирован, эта функция возвращается немедленно. lockedReadWriteLock не должен быть заблокирован рекурсивно, в противном случае эта функция не разблокирует его должным образом. lockedReadWriteLock будет разблокирован, и вызывающий поток будет блокироваться до тех пор, пока не будет выполнено одно из следующих условий:

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

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

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

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

void QWaitCondition::wakeAll()

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

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

void QWaitCondition::wakeOne()

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

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

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

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

Spec-Zone.ru

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