對生產者和消費者問題的另一個解決辦法是使用QWaitCondition,它允許線程在一定條件下喚醒其他線程。其中wakeOne()函數在條件滿足時隨機喚醒一個等待線程,而wakeAll()函數則在條件滿足時喚醒所有等待線程。
下面通過一個典型用例:生產者和消費者,來實現這二者之間的同步。整個工程就一個main.cpp,文件如下:
#include <QtCore/QCoreApplication> #include <QWaitCondition> #include <QThread> #include <QMutex> #include <iostream> const int DataSize = 100; const int BufferSize = 1; char buffer[BufferSize]; QWaitCondition bufferIsNotFull; QWaitCondition bufferIsNotEmpty; QMutex mutex; int usedSpace; class Producer : public QThread { protected: void run() { for (int i = 0; i < DataSize; ++i) { mutex.lock(); while (usedSpace == BufferSize) { bufferIsNotFull.wait(&mutex); } std::cerr<<"P"; ++usedSpace; bufferIsNotEmpty.wakeAll(); mutex.unlock(); } } }; class Consumer : public QThread { protected: void run() { for (int i = 0; i < DataSize; ++i) { mutex.lock(); while (usedSpace == 0) { bufferIsNotEmpty.wait(&mutex); } std::cerr<<"C"; --usedSpace; bufferIsNotFull.wakeAll(); mutex.unlock(); } std::cerr<<std::endl; } }; int main(int argc, char *argv[]) { Producer producer; Consumer consumer; producer.start(); consumer.start(); producer.wait(); consumer.wait(); return 0; }
當DataSize = 100, BufferSize = 1時,程序運行的界面如下,結果是可以預期的。生產者每次生產一個,消費者就消費一個。
當DataSize = 100, BufferSize = 10時,程序運行的界面如下,結果是不可預期的。這里只是列舉兩種情況。
情況之一:
情況之二: