http://blog.csdn.net/mznewfacer/article/details/6965799

QMutex类

一个线程可以锁定互斥量,并且在它锁定之后,其它线程就不能再锁定这个互斥量了,试图这样做的线程都会被阻塞直到互斥量被释放

    class MyClass
{
public:
void doStuff( int );
private:
QMutex mutex;
int a;
int b;
}; // 这里设置a为c,b为c*2。 void MyClass::doStuff( int c )
{
mutex.lock();
a = c;
b = c * ;
mutex.unlock();
}

QWaitCondition

线程等待的条件QWaitCondition指出发生了什么事情,阻塞将一直持续到这种事情发生。当某种事情发生了,QWaitCondition可以唤醒等待这一事件的线程之一或全部

    #include <qapplication.h>
#include <qpushbutton.h>
// 全局条件变量
QWaitCondition mycond;
// Worker类实现
class Worker : public QPushButton, public QThread
{
Q_OBJECT
public:
Worker(QWidget *parent = 0, const char *name = 0)
: QPushButton(parent, name)
{
setText("Start Working");
// 连接从QPushButton继承来的信号和我们的slotClicked()方法
connect(this, SIGNAL(clicked()), SLOT(slotClicked()));
// 调用从QThread继承来的start()方法……这将立即开始线程的执行
QThread::start();
}
public slots:
void slotClicked()
{ // 唤醒等待这个条件变量的一个线程
mycond.wakeOne();
}
protected:
void run()
{
// 这个方法将被新创建的线程调用……
while ( TRUE ) {
// 锁定应用程序互斥锁,并且设置窗口标题来表明我们正在等待开始工作
qApp->lock();
setCaption( "Waiting" );
qApp->unlock();
// 等待直到我们被告知可以继续
mycond.wait();
// 如果我们到了这里,我们已经被另一个线程唤醒……让我们来设置标题来表明我们正在工作
qApp->lock();
setCaption( "Working!" );
qApp->unlock();
// 这可能会占用一些时间,几秒、几分钟或者几小时等等,因为这个一个和GUI线程分开的线程,在处理事件时,GUI线程不会停下来……
do_complicated_thing();
}
}
};
// 主线程——所有的GUI事件都由这个线程处理。
int main( int argc, char **argv )
{
QApplication app( argc, argv );
// 创建一个worker……当我们这样做的时候,这个worker将在一个线程中运行
Worker firstworker( 0, "worker" );
app.setMainWidget( &worker );
worker.show();
return app.exec();
}

  只要你按下按钮,这个程序就会唤醒worker线程,这个线程将会进行并且做一些工作并且然后会回来继续等待被告知做更多的工作。如果当按钮被按下时,worker线程正在工作,那么就什么也不会发生。当线程完成了工作并且再次调用QWaitCondition::wait(),然后它就会被开始。

QWaitCondition
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;
}

  

Qt多线程编程总结(一)的更多相关文章

  1. Qt多线程编程总结(一)(所有GUI对象都是线程不安全的)

    Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法. 这个文档是提供给那些对多线程编程有丰富的知识和经验的听众的.推荐阅 ...

  2. Qt多线程编程中的对象线程与函数执行线程

    近来用Qt编写一段多线程的TcpSocket通信程序,被其中Qt中报的几个warning搞晕了,一会儿是说“Cannot create children for a parent that is in ...

  3. Qt -------- 多线程编程

    一.继承QThread(不推荐) 定义一个类,继承QThread,重写run(),当调用方法start(),启动一个线程,run()函数运行结束,线程结束. 二.继承QRunnable Qrunnab ...

  4. Qt多线程编程总结(二)——QMutex

    QMutex类提供的是线程之间的访问顺序化. QMutex的目的是保护一个对象.数据结构或者代码段,所以同一时间只有一个线程可以访问它.(在Java术语中,它和同步关键字“synchronized”很 ...

  5. C++11多线程编程

    1. 多线程编程 在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作.这种情况下就需要使用多线程,其中一 ...

  6. Qt 多线程和网络编程学习

    一,Qt多线程类学习 QThread类,开始一个新的线程就是开始执行重新实现QThread::run(),run()是默认现实调用exec(),QThread::start()开始线程的执行,run( ...

  7. Qt中的多线程编程

    http://www.ibm.com/developerworks/cn/linux/l-qt-mthrd/ Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功 ...

  8. [转] Qt 多线程学习

    Qt 多线程学习 转自:http://www.cnblogs.com/IT-BOY/p/3544220.html 最近的项目上用到了关于多线程的知识,自己也比较感兴趣,所以就拿了那本<C++ G ...

  9. QThread多线程编程经典案例分析

    传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...

随机推荐

  1. JSON.parse() JSON.stringify() eval() jQuery.parseJSON() 的区别

    http://www.jb51.net/article/81880.htm    :   jQuery.parseJSON(jsonString) : 将格式完好的JSON字符串转为与之对应的Java ...

  2. 转:JMeter 参数化之利用JDBC Connection Configuration从数据库读取数据并关联变量

    1.   下载mysql jar包 下载mysql jar包 http://dev.mysql.com/downloads/connector/j/ 网盘下载地址:mysql-connector-ja ...

  3. ios常见问题 经验之谈

    1.既然有问题我们该怎样解决 ? 首先大部分人都会去百度搜索来解决问题, 谁都不例外, 可是百度这东西会有很多误解, 甚至误人子弟, 同时解决问题的效率也不是很高, 如果是技术问题可以去: Googl ...

  4. LINQ里的“equals”和“==”的区别

    对于值类型,如果对象的值相等,则相等运算符 (==) 返回 true,否则返回 false.对于string 以外的引用类型,如果两个对象引用同一个对象,则 == 返回 true.对于 string ...

  5. mysql 数据列按照逗号转成行

    前言: 由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式.即同一个列中存储了多个属性值(具体结构见下表). 这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列转行的结果 ...

  6. SSH 两个表全套增删改(运动员住宿管理)

    0.创建如下oracle的命令 create table HOTALINFO ( HOTALID ) not null, HOTALNAME ) not null, HOTALADDRESS ) no ...

  7. 转Rollback后undo到底做了些什么?

    转自:http://biancheng.dnbcw.info/oracle/309191.html Rollback后undo到底做了些什么? 从概念上讲,undo正好与redo相对.当你对数据执行修 ...

  8. php使用iconv进行从utf-8转为gb2312字符编码出错或截断的解决方案

    iconv("GB2312","UTF-8",$text);修改为以下其中一种:1.iconv("UTF-8","GBK" ...

  9. [ An Ac a Day ^_^ ] CodeForces 680A Bear and Five Cards

    这两天回家了 家里电脑太卡 调试不方便 就只能写写水题了…… #include<stdio.h> #include<iostream> #include<algorith ...

  10. nefu 903 字符串去星

    字符串去星 Problem : 903 Time Limit : 1000ms Memory Limit : 65536K description 有一个字符串(长度小于100),要统计其中有多少个* ...