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

  下面通过一个典型用例:生产者和消费者,来实现这二者之间的同步。整个工程就一个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; 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;
}

  当DataSize = 100, BufferSize  = 1时,程序运行的界面如下,结果是可以预期的。生产者每次生产一个,消费者就消费一个。

  当DataSize = 100, BufferSize  = 10时,程序运行的界面如下,结果是不可预期的。这里只是列举两种情况。

  情况之一:

  情况之二:

 
http://www.cnblogs.com/venow/archive/2012/10/15/2725040.html

Qt的QWaitCondition(允许线程在一定条件下唤醒其他线程,这样对不间断上传可能比较适用)的更多相关文章

  1. Qt 进程和线程之三:线程同步、可重入与线程安全

    一.同步线程方法 使用线程的目的是允许代码并行运行,但是有时线程必须停止并等待其他线程.例如,如果两个线程试图同时写入相同的变量,结果是不确定的,所以需要同步线程.同步线程是一种保护共享资源等数据的常 ...

  2. Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)

    QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...

  3. Linux线程同步:条件变量

    条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用.使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化.一旦其它 ...

  4. linux线程同步(2)-条件变量

    一.概述                                                    上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...

  5. QT 线程池 + TCP 小试(一)线程池的简单实现

    *免分资源链接点击打开链接http://download.csdn.net/detail/goldenhawking/4492378 很久以前做过ACE + MFC/QT 的中轻量级线程池应用,大概就 ...

  6. UNIX环境高级编程——线程同步之条件变量以及属性

    条件变量变量也是出自POSIX线程标准,另一种线程同步机制.主要用来等待某个条件的发生.可以用来同步同一进程中的各个线程.当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量来 ...

  7. 四十二、Linux 线程——线程同步之条件变量之线程状态转换

    42.1 线程状态转换 42.1.1 状态转换图 42.1.2 一个线程计算,多个线程获取的案例 #include <stdio.h> #include <stdlib.h> ...

  8. 四十一、Linux 线程——线程同步之条件变量

    41.1 概念 41.1.1 条件变量的介绍 互斥锁的缺点是它只有两种状态:锁定和非锁定 条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足 条件变量内部是一个等待队列,放置等待 ...

  9. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

随机推荐

  1. C#7模范和实践

    C# 7 中的模范和实践   原文地址:https://www.infoq.com/articles/Patterns-Practices-CSharp-7 关键点 遵循 .NET Framework ...

  2. mac下装php5.6

    OS X10.11自带了php5.5,项目中使用的是php5.6,用brew install --without-apache --with-fpm --with-mysql php56装php5.6 ...

  3. vue router 传递参数

    vue-router 传参的方式 query 和params query 类似于get请求的传参方法 就是 ? 这种形式的 https://i.cnblogs.com/EditPosts.aspx?o ...

  4. 关于undefind

    var undefined = "东方云游"; alert(undefined); // undefined 不一定为undefined ie8(包含ie8)以下会返回 " ...

  5. python 反转列表

    翻转一个链表 您在真实的面试中是否遇到过这个题? Yes 样例 给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null 步骤是这样的: ...

  6. 理解 UWP 视图的概念,让 UWP 应用显示多个窗口(多视图)

    原文 理解 UWP 视图的概念,让 UWP 应用显示多个窗口(多视图) UWP 应用多是一个窗口完成所有业务的,事实上我也推荐使用这种单一窗口的方式.不过,总有一些特别的情况下我们需要用到不止一个窗口 ...

  7. Openstack部署总结:“部署过程Error: Local ip for ovs agent must be set when tunneling is enabled”问题

    问题叙述性说明 正在使用RDO当多节点部署测试,因为使用了一些老机器和机器类型的差异(一些HP的PC,有些DELL的PC).以下错误出现: Applying 192.168.40.107_neutro ...

  8. MVC模式简单介绍

    模型-视图-控件(model-View-Controller)MVC结构是一种开发模块的方法,它将数据存储和数据处理从数据的可视化表示中分离出来.存储和处理数据的组件称为模型,它包括模块的实际内容.表 ...

  9. STM32处理器AD难度整理

    1.STM32的AD变化,任务组可以转换成两组:规则组和注射组.随机序列按随机顺序变换多种渠道构成了一组转换.例如.能够完成转换中,例如按照以下顺序:通道3.通道8.通道2.通道2.通道0.通道2.通 ...

  10. matlab 求解 Ax=B 时所用算法

    x = A\B; x = mldivide(A, B); matlab 在这里的求解与严格的数学意义是不同的, 如果 A 接近奇异,matlab 仍会给出合理的结果,但也会提示警告信息: 如果 A 为 ...