使用QWaitCondition类解决生产者和消费者问题。
源文件“main.cpp”的具体内容如下:

#include <QCoreApplication>
#include <QWaitCondition>
#include <QMutex>
#include <QThread>
#include <stdio.h>
const int DataSize=1000;
const int BufferSize=80;
int buffer[BufferSize];
QWaitCondition bufferEmpty;
QWaitCondition bufferFull;
QMutex mutex; //使用互斥量保证对线程操作的原子性。
int numUsedBytes=0; //变量numUsedBytes表示存在多少“可用字节”。
int rIndex=0; //本例中启动了两个消费者线程,并且这两个线程读取同一个缓冲区,为了不重复读取,设置全局变量rIndex用于指示当前所读取缓冲区位置。

生产者线程Producer类继承自QThread类,其声明如下:

class Producer : public QThread
{public:
Producer();
void run();
};

Producer()构造函数无须实现:

Producer::Producer()
{}

Producer::run()函数的具体内容如下:

void Producer::run()
{
for(int i=0;i<DataSize;i++) // for循环中的所有语句都需要使用互斥量加以保护,以保证其操作的原子性。
{
mutex.lock();
if(numUsedBytes==BufferSize) //首先检查缓冲区是否已被填满。
bufferEmpty.wait(&mutex); //如果缓冲区已被填满,则等待“缓冲区有空位”(bufferEmpty变量)条件成立。wait()函数将互斥量解锁并在此等待。
buffer[i%BufferSize]=numUsedBytes; //如果缓冲区未被填满,则向缓冲区中写入一个整数值。
++numUsedBytes; //增加numUsedBytes变量
bufferFull.wakeAll(); //后唤醒等待“缓冲区有可用数据”(bufferEmpty变量)条件为“真”的线程。
mutex.unlock();
}
}

这里介绍一下Wait()函数:
wait()函数原型如下:

bool QWaitCondition::wait
(
QMutex * mutex,
unsigned long time = ULONG_MAX
)

① 参数mutex为一个锁定的互斥量。如果此参数的互斥量在调用时不是锁定的或者出现递归锁定的情况,则wait()函数将立刻返回。
② 参数time为等待时间。
调用wait()操作的线程使得作为参数的互斥量在调用前首先变为解锁定状态,然后自身被阻塞变为等待状态直到满足以下条件之一:
(1)其他线程调用了wakeOne()或者wakeAll()函数,这种情况下将返回“true”值。
(2)第2个参数time超时(以毫秒为单位),该参数默认情况下为ULONG_MAX,表示永不超时,这种情况下将返回“false”值。
(3)wait()函数返回前会将互斥量参数重新设置为锁定状态,从而保证从锁定状态到等待状态的原子性转换。

消费者线程Consumer类继承自QThread类,其声明如下:

class Consumer : public QThread
{public:
Consumer();
void run();
};

Consumer()构造函数中无须实现内容:

Consumer::Consumer()
{}

Consumer::run()函数的具体内容如下:

void Consumer::run()
{
forever
{
mutex.lock();
if(numUsedBytes==0)
bufferFull.wait(&mutex); //当缓冲区中无数据时,等待“缓冲区有可用数据”(bufferFull变量)条件成立。
printf("%ul::[%d]=%d\n",currentThreadId(),rIndex,buffer[rIndex]);// 当缓冲区中有可用数据即条件成立时,打印当前线程号和rIndex变量,以及其指示的当前可读取数据。这里为了区分究竟是哪一个消费者线程消耗了缓冲区里的数据,使用了QThread类的currentThreadId()静态函数输出当前线程的ID。这个ID在X11环境下是一个unsigned long 类型的值。
rIndex=(++rIndex)%BufferSize; //将rIndex变量循环加1
--numUsedBytes; // numUsedBytes变量减1,即可用的数据减1。
bufferEmpty.wakeAll(); //唤醒等待“缓冲区有空位”(bufferEmpty变量)条件的生产者线程。
mutex.unlock();
}
printf("\n");
}
main()函数的具体内容如下:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Producer producer;
Consumer consumerA;
Consumer consumerB;
producer.start();
consumerA.start();
consumerB.start();
producer.wait();
consumerA.wait();
consumerB.wait();
return a.exec();
}

程序最终的运行结果如下图所示:

QT学习:线程等待与唤醒相关推荐

  1. Windows事件等待学习笔记(二)—— 线程等待与唤醒

    Windows事件等待学习笔记(二)-- 线程等待与唤醒 要点回顾 等待与唤醒机制 可等待对象 可等待对象的差异 线程与等待对象 一个线程等待一个对象 实验 第一步:编译并运行以下代码 第二步:在Wi ...

  2. java队列等待唤醒_Java深入学习29:线程等待和唤醒的两个方案

    Java深入学习29:线程等待和唤醒的两个方案 模拟场景 一个门店,有一个店员,有消费者来消费商品(每次消费1件商品),有仓库人员来添加(生产)商品(每次生产1件商品),并假设库存上限是2. 基础代码 ...

  3. c++ linux 线程等待与唤醒_C++ Linux线程同步机制:POSIX信号量,互斥锁,条件变量...

    线程同步机制:POSIX 信号量,互斥量,条件变量 POSIX 信号量 常用的POSIX 信号量函数为如下5个: sem_init sem_destroy sem_wait sem_trywait s ...

  4. c++ linux 线程等待与唤醒_C++并发编程 等待与唤醒

    C++并发编程 等待与唤醒 条件变量 条件变量, 包括(std::condition_variable 和 std::condition_variable_any) 定义在 condition_var ...

  5. 【小白学java】D36》》》线程入门学习,线程同步机制 和 线程等待与唤醒机制

  6. c++ linux 线程等待与唤醒_Linux线程同步(互斥量、信号量、条件变量、生产消费者模型)...

    为什么要线程同步? 线程间有很多共享资源,都对一个共享数据读写操作,线程操作共享资源的先后顺序不确定,可能会造成数据的冲突 看一个例子 两个线程屏行对全局变量count++ (采用一个val值作为中间 ...

  7. c++ linux 线程等待与唤醒_Linux驱动程序基石-POLL机制(附.视频)

    今天<升级版全系列嵌入式视频_入门篇>新增一节视频:19.2_POLL机制 时长24分钟,免费观看 何为POLL机制? 给驱动程序加一个闹钟,让APP不必死等数据: 既可以快速掌握 POL ...

  8. Android消息机制(Handler机制) - 线程的等待和唤醒

    我们都知道,Android的Handler机制,会在线程中开启消息循环,不断的从消息队列中取出消息,这个机制保证了主线程能够及时的接收和处理消息. 通常在消息队列中(MessageQueue)中没有消 ...

  9. 线程的等待和唤醒机制

    目录 第一种方式:synchronized + wait + notify: 第二种方式:Lock + await + signal : 第三种方式:LockSupport + park +unpar ...

最新文章

  1. android PhotoView的用法
  2. 震惊 Guava 竟然有坑
  3. android技术内幕心得
  4. PHP之preg_replace()与ereg_replace()正则匹配比较讲解
  5. 全新释放 | RealSight APM, 让客户的极致数字体验成为可能
  6. 能用来写安卓吗_iPad能代替笔记本吗,除了看剧还能用来做什么?
  7. 创建一个Flash站点的十大技巧
  8. matplotlib color 参数
  9. epoll原理_Epoll源码阅读手札
  10. 基于Ubuntu的ESP32平台搭建
  11. Eurek自我保护机制
  12. EDM大师独家收藏的30个绝佳节日邮件模板
  13. VNPY量化交易(一)
  14. openffice安装(windows和linux)
  15. 猫游记页游mysql_5款曾经极其火爆的页游,最后一款90后没听过80后才玩过
  16. VIVO NEX3高层预热,差0.4到100%屏占比,这得让多少人心动
  17. 51单片机电机测速程序c语言,基于51单片机光电编码器测速.doc
  18. 橘子学ES19之词项搜索全文检索
  19. jquery入门介绍
  20. postgresql 官网学习文档

热门文章

  1. 预训练模型真的越大越好吗?听听他们怎么说
  2. 深度强化学习的 18 个关键问题 | PaperDaily #30
  3. label smoothing(标签平滑)
  4. 并查集(Union-Find-Set)简洁而高效地处理连通分量的查询与合并
  5. 【SQL编程】Greenplum 与 MySQL 数据库获取周几函数及函数结果保持一致的方法
  6. python面向对象继承_Python 面向对象 --- 继承
  7. 深入浅出在NIO技术中,如何理解直接缓冲区要比非直接缓冲区效率高?
  8. Selenium3+MoocTest环境搭建常见问题解决方案
  9. Vue + Element UI + Moment.js——el-table-column的时间戳格式转换解决方案
  10. 测试软件ipc,IPC整机测试工具