对生产者和消费者问题的另一个解决办法是使用QWaitCondition,它允许线程在一定条件下唤醒其他线程。其中wakeOne()函数在条件满足时随机唤醒一个等待线程,而wakeAll()函数则在条件满足时唤醒所有等待线程。

1、bool wait(QMutex * mutex,unsigned long time = ULONG_MAX)
1) 释放锁定的mutex
 2) 在线程对象上等待

mutex必须由调用线程进行初锁定 。注意调用wait的话,会自动调用unlock解锁之前锁住的资源,不然会造成死锁。线程1等待线程2来改变共享资源,从而达到一定的条件然后发出信号,使得线程1从wait中的阻塞状态中被唤醒。但是线程2想改变资源,却无法办到,因为线程1调用lock之后就在wait中blocking,了但是没有及时的unlock,那么这就构成了死锁的条件。所以说wait函数除了使调用线程切换到内核态之外,还自动unlock(&mutex)。

2、void wakeOne()
      这将会唤醒所有等待QWaitCondition的线程。这些线程被唤醒的顺序依赖于操组系统的调度策略,并且不能被控制或预知。

3、void wakeAll()

这将会唤醒所有等待QWaitCondition的线程中的一个线程。这个被唤醒的线程依赖于操组系统的调度策略,并且不能被控制或预知。

  下面通过一个典型用例:生产者和消费者,来实现这二者之间的同步。整个工程就一个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 = 0; 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;
} https://blog.csdn.net/skc361/article/details/19409527

最新文章

  1. 经典算法C++版(参考一线码农博文)
  2. js代码学习
  3. [转]jQuery EasyUI自定义DataGrid的Editor
  4. Visitor模式,Decorator模式,Extension Object模式
  5. ooj1057: M的整数倍DP
  6. shell之并行
  7. Java实现 Base64、MD5、MAC、HMAC加密(转)
  8. .NET Core微服务之基于Exceptionless实现分布式日志记录
  9. 数电基础之《OC门》
  10. springboot学习——第二集:整合Mybaits
  11. 鸟哥的 Linux 私房菜Shell Scripts篇(三)
  12. empty 与 remove 的区别
  13. AngularJS 路由及SPA理解
  14. JAVA 画图板实现(基本画图功能+界面UI)二、功能实现及重绘实现
  15. pgAdmin4 汉化
  16. JavaScript函数作用域与对象以及实用技巧
  17. ubuntu 18.04 安装 flash
  18. windows下的虚拟内存分配分析
  19. 微博短链接的生成算法(Java版本)
  20. 可视化库-Matplotlib-盒图(第四天)

热门文章

  1. leetCode 82.Remove Duplicates from Sorted List II (删除排序链表的反复II) 解题思路和方法
  2. CentOS6.4安装Docker
  3. 空间矢量数据(.shp文件)之JAVA操作
  4. dlmalloc 2.8.6 源代码具体解释(5)
  5. vim中使用正則表達式
  6. js -- canvas img 封装
  7. POJ 3049 DFS
  8. 图形界面备份Linux系统介绍
  9. Android 将HTML5封装成android应用APK文件的几种方法
  10. hbase xshell