多线程中QWaitCondition的应用

         QWaitCondition 允许线程在某些情况发生时唤醒另外的线程。一个或多个线程可以阻塞等待一QWaitCondition ,用wakeOne()或wakeAll()设置一个条件。wakeOne()随机唤醒一个,wakeAll()唤醒所有。
下面的例子中,生产者首先必须检查缓冲是否已满(numUsedBytes==BufferSize),如果是,线程停下来等待bufferNotFull条件。如果不是,在缓冲中生产数据,增加numUsedBytes,激活条件 bufferNotEmpty。使用mutex来保护对numUsedBytes的访问。另外,QWaitCondition::wait()接收一个mutex作为参数,这个mutex应该被调用线程初始化为锁定状态。在线程进入休眠状态之前,mutex会被解锁。而当线程被唤醒时,mutex会处于锁定状态,而且,从锁定状态到等待状态的转换是原子操作,这阻止了竞争条件的产生。当程序开始运行时,只有生产者可以工作。消费者被阻塞等待bufferNotEmpty条件,一旦生产者在缓冲中放入一个字节,bufferNotEmpty条件被激发,消费者线程于是被唤醒。


C/C++ code
 
    
const int DataSize = 100000 ; const int BufferSize = 8192 ; char buffer[BufferSize]; QWaitCondition bufferNotEmpty; QWaitCondition bufferNotFull; QMutex mutex; int numUsedBytes = 0 ; class Producer : public QThread { public : void run(); }; void Producer::run() { qsrand(QTime( 0 , 0 , 0 ).secsTo(QTime::currentTime())); for ( int i = 0 ; i < DataSize; ++ i) { mutex. lock (); if (numUsedBytes == BufferSize) bufferNotFull.wait( & mutex); mutex.unlock(); buffer[i % BufferSize] = " ACGT " [( int )qrand() % 4 ]; mutex. lock (); ++ numUsedBytes; bufferNotEmpty.wakeAll(); mutex.unlock(); } } class Consumer : public QThread { public : void run(); }; void Consumer::run() { for ( int i = 0 ; i < DataSize; ++ i) { mutex. lock (); if (numUsedBytes == 0 ) bufferNotEmpty.wait( & mutex); mutex.unlock(); fprintf(stderr, " %c " , buffer[i % BufferSize]); mutex. lock (); -- numUsedBytes; bufferNotFull.wakeAll(); mutex.unlock(); } fprintf(stderr, " \n " ); } int main( int argc, char * argv[]) { QCoreApplication app(argc, argv); Producer producer; Consumer consumer; producer.start(); consumer.start(); producer.wait(); consumer.wait(); return 0 ; }

你可能感兴趣的:(QT相关)