Qt 多线程学习

转自:http://www.cnblogs.com/IT-BOY/p/3544220.html

最近的项目上用到了关于多线程的知识,自己也比较感兴趣,所以就拿了那本《C++ GUI Qt4 编程》来学习。

这本书的第14章是关于多线程的知识,使用的Qt版本是Qt4.x。在下用的是最新的Qt 5.2,所以代码上有一些不兼容,稍加修改就可以运行了。

Qt的多线程简单来说就是继承QThread类,重载run()函数,start()启动线程。首先来看下书上的第一个例子:(修改版的代码已上传,点击下载

class Thread : public QThread
{
Q_OBJECT
public:
Thread(QString message = "", QObject *parent = NULL);
~Thread();
void setMessage(QString);
QString getMessage(); void stop(); protected:
void run(); private:
QString message;
volatile bool stopped;
};

Thread类继承了QThread类,并实现了run函数。stopped变量前面的volatile声明stopped为易失性变量,这样每次读取stopped时都是最新的值。

继续看Thread类的实现:

Thread::Thread(QString message, QObject *parent) :
stopped(false)
, QThread(parent)
, message(message)
{
} Thread::~Thread()
{
this->stop();
this->wait();
qDebug() << this;
} void Thread::setMessage(QString message)
{
this->message = message;
} QString Thread::getMessage()
{
return this->message;
} void Thread::stop()
{
stopped = true;
} void Thread::run()
{
while (!stopped)
std::cerr << qPrintable(message);
stopped = false;
std::cerr << std::endl;
}

初始化时将stopped设置为false,run函数中持续检查stopped的值,为true时才退出。

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
QPushButton *buttonQuit = new QPushButton(QString::fromLocal8Bit("Quit"));
connect(buttonQuit, &QPushButton::clicked, this, &Dialog::close); QBoxLayout *layout = new QBoxLayout(QBoxLayout::LeftToRight, this); QStringList list = QString("ABCDEFGHIJKLMN").split("",QString::SkipEmptyParts); foreach (QString name, list)
{
Thread *thread = new Thread(name, this);
QPushButton *button = new QPushButton(QString("Start ")+name, this);
mappingTable.insert(button, thread);
connect(button, &QPushButton::clicked, this, &Dialog::startOrStopThread);
layout->addWidget(button);
} layout->addWidget(buttonQuit);
this->setLayout(layout);
} void Dialog::startOrStopThread()
{
QPushButton *buttonNow = dynamic_cast<QPushButton*>(sender());
Thread *threadNow = (Thread*)mappingTable[buttonNow]; if (threadNow == NULL) return; if(threadNow->isRunning())
{
threadNow->stop();
buttonNow->setText( buttonNow->text().replace(QString("Stop"),QString("Start")) );
}
else
{
threadNow->start();
buttonNow->setText( buttonNow->text().replace(QString("Start"),QString("Stop")) );
}
}

在Dialog界面类中,将button与thread实现一一对应的连接,在槽函数中就可以方便的找到对应的线程了。其中mappingTable是QMap<QObject*, QObject*>类型的。

这样就可以方便的实现多个线程的修改,如下图:

另外,第四个例子对我也很有启发:

TransactionThread::TransactionThread(QObject *parent) :
QThread(parent)
{
start();
} TransactionThread::~TransactionThread()
{
{
QMutexLocker locker(&mutex); while (!transactions.isEmpty())
delete transactions.dequeue(); transactionCondition.wakeOne();
} wait();
} void TransactionThread::addTransaction(Transaction *transaction)
{
QMutexLocker locker(&mutex);
transactions.enqueue(transaction);
transactionCondition.wakeOne();
} void TransactionThread::run()
{
Transaction *transaction = ;
QImage oldImage; forever
{
{
QMutexLocker locker(&mutex); if (transactions.isEmpty())
transactionCondition.wait(&mutex); if (transactions.isEmpty())
break; transaction = transactions.dequeue();
oldImage = currentImage;
} emit transactionStarted(transaction->message(), );
QImage newImage = transaction->apply(oldImage);
delete transaction; {
QMutexLocker locker(&mutex);
currentImage = newImage; if (transactions.isEmpty())
emit allTransactionsDone();
}
}
} void TransactionThread::setImage(const QImage& image)
{
QMutexLocker locker(&mutex);
currentImage = image;
} QImage TransactionThread::getImage()
{
QMutexLocker locker(&mutex);
return currentImage;
}

以上为线程实现的关键代码。在读取和写入从线程与主线程共享的变量时,都要使用mutex互斥变量。使用QMutexLocker locker(&mutex)也更方便,在构造是lock,析构时unlock,临时变量超过了作用域自然被析构,不得不说实现者的方法很巧妙啊。至于transactionCondition.wait(&mutex)则是等待条件。当事务队列为空时,等待事务加入,或者析构。加入事务时唤醒即可,即transactionCondition.wakeOne()。

[转] Qt 多线程学习的更多相关文章

  1. Qt 多线程学习

    最近的项目上用到了关于多线程的知识,自己也比较感兴趣,所以就拿了那本<C++ GUI Qt4 编程>来学习. 这本书的第14章是关于多线程的知识,使用的Qt版本是Qt4.x.在下用的是最新 ...

  2. Qt多线程学习:创建多线程

    [为什么要用多线程?] 传统的图形用户界面应用程序都仅仅有一个运行线程,而且一次仅仅运行一个操作.假设用户从用户界面中调用一个比較耗时的操作,当该操作正在运行时,用户界面一般会冻结而不再响应.这个问题 ...

  3. Qt多线程学习-用例子来理解多线程(转),这个是我看过最好的文章,总结很详细(感觉exec()的作用就是保持线程不退出,这样方便随时处理主线程发来的信号,是一种非常别致的思路)good

    01 class MThread :public QThread 02 { 03 public: 04     MThread(); 05     ~MThread(); 06     virtual ...

  4. Qt多线程学习-用例子来理解多线程

    文章出处:DIY部落(http://www.diybl.com/course/3_program/c/c_js/20090303/157373_3.html) POINT 1:QThread类的实例与 ...

  5. QT多线程学习

    一.想要使用Qthread必须先创建,继承Qthread的类. #ifndef THREADTEST_H #define THREADTEST_H #include <QThread> # ...

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

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

  7. QT入门学习笔记2:QT例程

    转至:http://blog.51cto.com/9291927/2138876 Qt开发学习教程 一.Qt开发基础学习教程 本部分博客主要根据狄泰学院唐老师的<QT实验分析教程>创作,同 ...

  8. 【QT】 Qt多线程的“那些事”

    目录 一.前言 二.QThread源码浅析 2.1 QThread类的定义源码 2.2 QThread::start()源码 2.3 QThreadPrivate::start()源码 2.4 QTh ...

  9. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

随机推荐

  1. IOS 提交审核,遇到Missing Push Notification Entitlement 问题。

    貌似不影响提交........还是有人提交成了. 昨天晚上提交软件审核,遇到了Missing Push Notification Entitlement 的问题. 问题起因:这个版本我添加了PUSH推 ...

  2. TKStudio 4.6IDE Warning: L6310W: Unable to find ARM libraries.

    我也遇到了同样的问题.搞了很久,按下面的操解决了 内容转至:http://bbs.zlgmcu.com/dv_rss.asp?s=xh&boardid=43&id=23032& ...

  3. Python Tricks 若干

    赵斌 - APRIL 29, 2015 在 python 代码中可以看到一些常见的 trick,在这里做一个简单的小结. json 字符串格式化 在开发 web 应用的时候经常会用到 json 字符串 ...

  4. Python - 装饰器使用过程中的误区

    曾灵敏 - APRIL 27, 2015 装饰器基本概念 大家都知道装饰器是一个很著名的设计模式,经常被用于AOP(面向切面编程)的场景,较为经典的有插入日志,性能测试,事务处理,Web权限校验, C ...

  5. 初步体验javascript try catch机制

    javascript在ECMAScript3中引入了try catch finally机制,大致原理和其他语言一样. 我们也可以自定义错误事件. 但是事先声明:我们自定义的错误事件,只支持对name. ...

  6. String Reduction

    问题出自这里 问题描述: Given a string consisting of a,b and c's, we can perform the following operation: Take ...

  7. 【C语言】二维数组做形参

    二维数组有两种形式: ①在栈上:         int a[4][4] = {...}; ②在堆堆上:          int ** a = new int *[4];           for ...

  8. CSS Animatie是一款在线制作CSS3动画的工具,可以在线直接制作CSS3动画效果,生成代码

    CSS Animatie是一款在线制作CSS3动画的工具,可以在线直接制作CSS3动画效果,生成代码 CSS Animatie 彩蛋爆料直击现场 CSS Animatie是一款在线制作CSS3动画的工 ...

  9. netaddr 0.7.12

    Pythonic manipulation of IPv4, IPv6, CIDR, EUI and MAC network addresses https://pypi.python.org/pyp ...

  10. POJ 2017

    #include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("t ...