现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

多线程中QWaitCondition的应用

2015-02-06 23:06 工业·编程 ⁄ 共 1693字 ⁄ 字号 暂无评论

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

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

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;

}

给我留言

留言无头像?