• 3385阅读
  • 0回复

[提问]QT多线程QWaitCondition的问题 [复制链接]

上一主题 下一主题
离线suese
 

只看楼主 倒序阅读 楼主  发表于: 2012-03-02

先来一篇资料文章


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

  1. const int DataSize = 100000;
  2. const int BufferSize = 8192;
  3. char buffer[BufferSize];
  4. QWaitCondition bufferNotEmpty;
  5. QWaitCondition bufferNotFull;
  6. QMutex mutex;
  7. int numUsedBytes = 0;
  8. class Producer : public QThread
  9. {
  10. public:
  11.      void run();
  12. };
  13. void Producer::run()
  14. {
  15.      qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
  16.      for (int i = 0; i < DataSize; ++i) {
  17.          mutex.lock();
  18.          if (numUsedBytes == BufferSize)
  19.              bufferNotFull.wait(&mutex);
  20.          mutex.unlock();
  21.          buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];
  22.          mutex.lock();
  23.          ++numUsedBytes;
  24.          bufferNotEmpty.wakeAll();
  25.          mutex.unlock();
  26.      }
  27. }
  28. class Consumer : public QThread
  29. {
  30. public:
  31.      void run();
  32. };
  33. void Consumer::run()
  34. {
  35.      for (int i = 0; i < DataSize; ++i) {
  36.          mutex.lock();
  37.          if (numUsedBytes == 0)
  38.              bufferNotEmpty.wait(&mutex);
  39.          mutex.unlock();
  40.          fprintf(stderr, "%c", buffer[i % BufferSize]);
  41.          mutex.lock();
  42.          --numUsedBytes;
  43.          bufferNotFull.wakeAll();
  44.          mutex.unlock();
  45.      }
  46.      fprintf(stderr, "\n");
  47. }
  48. int main(int argc, char *argv[])
  49. {
  50.      QCoreApplication app(argc, argv);
  51.      Producer producer;
  52.      Consumer consumer;
  53.      producer.start();
  54.      consumer.start();
  55.      producer.wait();
  56.      consumer.wait();
  57.      return 0;
  58. }
线程1锁定mutex >> 进入bufferNotFull.wait(&mutex); >> mutex变成非锁定
线程2锁定mutex >> bufferNotFull.wakeAll(); >> 线程1被唤醒,按上文红色所述,线程1被唤醒后mutex会立即锁定,而此时线程2的mutex还在锁定状态,这不是竞争了么???


求答疑解惑
快速回复
限100 字节
 
上一个 下一个