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!";
}