Qt 线程等待条件
概念
Qt提供了QWaitCondition类实现“等待条件”式的线程控制方法,它让线程阻塞在等待条件的地方,直到条件满足后才继续执行下去。也就是说,QWaitCondition可以使一个线程在满足一定条件时通知其他多个线程,使它们及时作出响应。
QWaitCondition类成员函数
函数名称 | 函数描述 |
---|---|
QWaitCondition() | 构造并初始化对象 |
wai() | 解锁互斥量,并阻塞等待唤醒条件 |
wakeAll() | 唤醒所有处于等待状态的线程,线程唤醒的顺序不确定,由操作系统的调度策略决定 |
wakeOne() | 唤醒一个处于等待状态的线程,唤醒哪个线程不确定,由操作系统的调度策略决定 |
notify_all() | 相当于wakeAll().此函数兼容STL |
notify_one() | 相当于wakeOne().此函数兼容STL |
程序示例
读取线程启动进入等待唤醒状态,当写入数据线程写入数据完成后唤醒所有读取线程,读取线程再继续执行;
// 公共数据和锁&等待唤醒对象
class TestData
{
public:static int sm_nSharedNumber;static QReadWriteLock sm_ReadWriteLock;static QWaitCondition sm_WaitCondition;
};int TestData::sm_nSharedNumber = 10;
QReadWriteLock TestData::sm_ReadWriteLock;
QWaitCondition TestData::sm_WaitCondition;// 写入数据线程
class WorkThread2 : public QThread
{Q_OBJECT
public:explicit WorkThread2(QObject *parent = nullptr);~WorkThread2() = default;protected:void run() override;
};WorkThread2::WorkThread2(QObject *parent) : QThread(parent)
{}void WorkThread2::run()
{TestData::sm_ReadWriteLock.lockForWrite();TestData::sm_nSharedNumber += 5;TestData::sm_nSharedNumber *= 10;qDebug() << QString::fromLocal8Bit("write1 ----- 线程2 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;qDebug() << QString::fromLocal8Bit("write2 ----- 线程2 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;qDebug() << QString::fromLocal8Bit("write3 ----- 线程2 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;TestData::sm_WaitCondition.wakeAll();TestData::sm_ReadWriteLock.unlock();
}// 读取数据线程
class WorkThread1 : public QThread
{Q_OBJECT
public:explicit WorkThread1(QObject *parent = nullptr);~WorkThread1() = default;protected:void run() override;};WorkThread1::WorkThread1(QObject *parent) : QThread(parent)
{}void WorkThread1::run()
{TestData::sm_ReadWriteLock.lockForRead();// 先解锁 QReadWriteLock ,其他线程可以使用 QReadWriteLockTestData::sm_WaitCondition.wait(&TestData::sm_ReadWriteLock);qDebug() << QString::fromLocal8Bit("read1 ----- 线程1 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;msleep(10);qDebug() << QString::fromLocal8Bit("read2 ----- 线程1 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;msleep(20);qDebug() << QString::fromLocal8Bit("read3 ----- 线程1 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;TestData::sm_ReadWriteLock.unlock();
}// 测试函数
void Test()
{unique_ptr<WorkThread1> upThread11 = std::make_unique<WorkThread1>();unique_ptr<WorkThread1> upThread12 = std::make_unique<WorkThread1>();unique_ptr<WorkThread1> upThread13 = std::make_unique<WorkThread1>();unique_ptr<WorkThread2> upThread2 = std::make_unique<WorkThread2>();// 先启动读取函数,让函数处在等待阻塞状态upThread11->start();upThread12->start();upThread13->start();QThread::msleep(10);upThread2->start();upThread11->wait();upThread12->wait();upThread13->wait();upThread2->wait();qDebug() << "Over!";
}