QWaitCondition Class

QWaitCondition 类为同步线程提供了一个条件变量。更多

Header: #include <QWaitCondition>
CMake.QWaitCondition 类 find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core

注意:该类中的所有函数都是线程安全的

公共函数

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

详细说明

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();
}

互斥是必要的,因为两个线程试图同时改变同一变量的值,其结果是不可预测的。

等待条件是一种强大的线程同步原语。使用等待条件的生产者和消费者示例展示了如何使用 QWaitCondition 代替QSemaphore 来控制对生产者线程和消费者线程共享的循环缓冲区的访问。

另请参阅 QMutex,QSemaphore,QThread使用等待条件的生产者和消费者

成员函数文档

QWaitCondition::QWaitCondition()

构造一个新的等待条件对象。

[noexcept] QWaitCondition::~QWaitCondition()

销毁等待条件对象。

void QWaitCondition::notify_all()

提供此函数是为了与 STL 兼容。它等同于wakeAll()。

void QWaitCondition::notify_one()

提供此函数是为了与 STL 兼容。它等同于wakeOne()。

bool QWaitCondition::wait(QMutex *lockedMutex, QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))

释放lockedMutex 并等待等待条件。lockedMutex 最初必须被调用线程锁定。如果lockedMutex 未处于锁定状态,则行为未定义。如果lockedMutex 是递归互斥项,则此函数立即返回。lockedMutex 将被解锁,调用线程将阻塞,直到满足上述任一条件:

  • 另一个线程使用wakeOne() 或wakeAll() 发出信号。在这种情况下,此函数将返回 true。
  • 到达deadline 指定的最后期限。如果deadlineQDeadlineTimer::Forever (默认值),则等待永远不会超时(事件必须发出信号)。如果等待超时,该函数将返回 false。

lockedMutex 将返回到锁定状态。提供此函数是为了实现从锁定状态到等待状态的原子转换。

另请参阅 wakeOne() 和wakeAll()。

bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))

释放lockedReadWriteLock 并等待等待条件。lockedReadWriteLock 最初必须被调用线程锁定。如果lockedReadWriteLock 未处于锁定状态,则此函数立即返回。lockedReadWriteLock 不得被递归锁定,否则此函数将无法正常释放锁。lockedReadWriteLock 将被解锁,调用线程将阻塞,直到满足上述任一条件:

  • 另一个线程使用wakeOne() 或wakeAll() 发出信号。在这种情况下,该函数将返回 true。
  • 到达deadline 指定的最后期限。如果deadlineQDeadlineTimer::Forever (默认值),则等待永远不会超时(事件必须发出信号)。如果等待超时,该函数将返回 false。

lockedReadWriteLock 将返回到锁定状态。提供此函数是为了实现从锁定状态到等待状态的原子转换。

另请参阅 wakeOne() 和wakeAll()。

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

这是一个重载函数。

释放lockedMutex ,并在等待条件下等待time 毫秒。

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

这是一个重载函数。

释放lockedReadWriteLock ,并在等待条件下等待time 毫秒。

void QWaitCondition::wakeAll()

唤醒等待条件下的所有线程。唤醒线程的顺序取决于操作系统的调度策略,无法控制或预测。

另请参阅 wakeOne().

void QWaitCondition::wakeOne()

唤醒等待条件下的一个线程。被唤醒的线程取决于操作系统的调度策略,无法控制或预测。

如果要唤醒特定的线程,解决方案通常是使用不同的等待条件,让不同的线程在不同的条件下等待。

另请参见 wakeAll().

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.