QT 线程之QWaitCondition(深入理解)

前言:

转载请附上连接,本帖原创请勿照抄。

QWaitCondition 允许线程在某些情况发生时唤醒另外的线程。一个或多个线程可以阻塞等待一QWaitCondition ,用wakeOne()或wakeAll()设置一个条件。wakeOne()随机唤醒一个,wakeAll()唤醒所有。

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

原始Demo:

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 线程之QSemaphore(深入理解)

看完基本就能理解这篇内容,基本上就是新建了两个QWaitCondition ,同时运行两个线程,线程A运行达成uf条件调用 bufferNotFull.wait(&mutex); 阻塞线程

运行到线程B的时候,等待B执行完后调用 bufferNotEmpty.wakeAll(); 来唤醒所有被阻塞的线程;

其它线程文章:

QT 初识线程(简单实现):https://blog.csdn.net/qq_37529913/article/details/110127940

QT QMutex使用详解:https://blog.csdn.net/qq_37529913/article/details/110187452

QT 线程之QSemaphore(深入理解):https://blog.csdn.net/qq_37529913/article/details/110187121

QT线程 Emit、Sgnals、Slot详细解释:https://blog.csdn.net/qq_37529913/article/details/110211435

QT 线程之QWaitCondition(深入理解):https://blog.csdn.net/qq_37529913/article/details/110212704

Qt 多线程之线程事件循环(深入理解):https://blog.csdn.net/qq_37529913/article/details/110229382

QT线程之QObjects(深入理解):https://blog.csdn.net/qq_37529913/article/details/110228837

QT线程之可重入与线程安全(深入理解):https://blog.csdn.net/qq_37529913/article/details/110224166

QT之浅拷贝、深拷贝、隐式共享(深度理解必看文章):https://blog.csdn.net/qq_37529913/article/details/110235596

QT 隐式共享机制对STL样式迭代器的影响:https://blog.csdn.net/qq_37529913/article/details/110252454

猜你喜欢

转载自blog.csdn.net/qq_37529913/article/details/110212704