QT学习:线程等待与唤醒
生活随笔
收集整理的這篇文章主要介紹了
QT学习:线程等待与唤醒
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用QWaitCondition類解決生產者和消費者問題。
源文件“main.cpp”的具體內容如下:
生產者線程Producer類繼承自QThread類,其聲明如下:
class Producer : public QThread { public: Producer(); void run(); };Producer()構造函數無須實現:
Producer::Producer() { }Producer::run()函數的具體內容如下:
void Producer::run() { for(int i=0;i<DataSize;i++) // for循環中的所有語句都需要使用互斥量加以保護,以保證其操作的原子性。 { mutex.lock(); if(numUsedBytes==BufferSize) //首先檢查緩沖區是否已被填滿。 bufferEmpty.wait(&mutex); //如果緩沖區已被填滿,則等待“緩沖區有空位”(bufferEmpty變量)條件成立。wait()函數將互斥量解鎖并在此等待。 buffer[i%BufferSize]=numUsedBytes; //如果緩沖區未被填滿,則向緩沖區中寫入一個整數值。 ++numUsedBytes; //增加numUsedBytes變量 bufferFull.wakeAll(); //后喚醒等待“緩沖區有可用數據”(bufferEmpty變量)條件為“真”的線程。 mutex.unlock(); } }這里介紹一下Wait()函數:
wait()函數原型如下:
① 參數mutex為一個鎖定的互斥量。如果此參數的互斥量在調用時不是鎖定的或者出現遞歸鎖定的情況,則wait()函數將立刻返回。
② 參數time為等待時間。
調用wait()操作的線程使得作為參數的互斥量在調用前首先變為解鎖定狀態,然后自身被阻塞變為等待狀態直到滿足以下條件之一:
(1)其他線程調用了wakeOne()或者wakeAll()函數,這種情況下將返回“true”值。
(2)第2個參數time超時(以毫秒為單位),該參數默認情況下為ULONG_MAX,表示永不超時,這種情況下將返回“false”值。
(3)wait()函數返回前會將互斥量參數重新設置為鎖定狀態,從而保證從鎖定狀態到等待狀態的原子性轉換。
消費者線程Consumer類繼承自QThread類,其聲明如下:
class Consumer : public QThread { public: Consumer(); void run(); };Consumer()構造函數中無須實現內容:
Consumer::Consumer() { }Consumer::run()函數的具體內容如下:
void Consumer::run() { forever { mutex.lock(); if(numUsedBytes==0) bufferFull.wait(&mutex); //當緩沖區中無數據時,等待“緩沖區有可用數據”(bufferFull變量)條件成立。 printf("%ul::[%d]=%d\n",currentThreadId(),rIndex,buffer[rIndex]);// 當緩沖區中有可用數據即條件成立時,打印當前線程號和rIndex變量,以及其指示的當前可讀取數據。這里為了區分究竟是哪一個消費者線程消耗了緩沖區里的數據,使用了QThread類的currentThreadId()靜態函數輸出當前線程的ID。這個ID在X11環境下是一個unsigned long 類型的值。 rIndex=(++rIndex)%BufferSize; //將rIndex變量循環加1 --numUsedBytes; // numUsedBytes變量減1,即可用的數據減1。 bufferEmpty.wakeAll(); //喚醒等待“緩沖區有空位”(bufferEmpty變量)條件的生產者線程。 mutex.unlock(); } printf("\n"); } main()函數的具體內容如下: int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Producer producer; Consumer consumerA; Consumer consumerB; producer.start(); consumerA.start(); consumerB.start(); producer.wait(); consumerA.wait(); consumerB.wait(); return a.exec(); }程序最終的運行結果如下圖所示:
總結
以上是生活随笔為你收集整理的QT学习:线程等待与唤醒的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QT学习:多线程控制
- 下一篇: QT学习:多线程运用