一、继承QThread(不推荐)

定义一个类,继承QThread,重写run(),当调用方法start(),启动一个线程,run()函数运行结束,线程结束。

二、继承QRunnable

Qrunnable是所有可执行对象的基类。我们可以继承Qrunnable,并重写虚函数void QRunnable::run () ,然后用QThreadPool让我们的一个QRunnable对象在另外的线程中运行,如果autoDelete()返回true(默认),那么QThreadPool将会在run()运行结束后自动删除Qrunnable对象。可以调用void QRunnable::setAutoDelete ( bool autoDelete )更改auto-deletion标记。需要注意的是,必须在调用QThreadPool::start()之前设置,在调用QThreadPool::start()之后设置的结果是未定义的。

下面是我写的简单的例子:

class Runnable:public QRunnable
{
//Q_OBJECT 注意了,Qrunnable不是QObject的子类。
public: Runnable();
~Runnable(); voidrun();
};
Runnable::Runnable():QRunnable()
{ }
Runnable::~Runnable()
{
cout<<"~Runnable()"<<endl;
} void Runnable::run()
{
cout<<"Runnable::run()thread :"<<QThread::currentThreadId()<<endl;
cout<<"dosomething ...."<<endl;
} int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cout<<"mainthread :"<<QThread::currentThreadId()<<endl;
Runnable runObj;
QThreadPool::globalInstance()->start(&runObj);
returna.exec();
}

由结果可看出,run()确实是在不同于主线程的另外线程中运行的,而且在运行结束后就调用了析构函数,因为默认是可以自动被销毁的。

我们可以对同一个对象多次调用QThreadPool::start(),如果是可以自动被销毁的,Qrunnable对象会在最后一个线程离开了run函数之后才被销毁的。

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cout<<"mainthread :"<<QThread::currentThreadId()<<endl;
Runnable runObj;
QThreadPool::globalInstance()->start(&runObj);
QThreadPool::globalInstance()->start(&runObj);
QThreadPool::globalInstance()->start(&runObj);
returna.exec();
}

我三次调用QThreadPool::globalInstance()->start(&runObj);,但是在三次都执行完之后才运行析构函数。

这种新建线程的方法的最大的缺点就是:不能使用Qt的信号—槽机制,因为Qrunnable不是继承自QObject。所以我们要想知道线程是否运行结束或获取运行结果可能会比较麻烦。还有就是我们不能直接调用run()启动线程,必须借助于QthreadPool。

但是这种方法的好处就是,可以让QThreadPool来管理线程,QThreadPool会自动的清理我们新建的Qrunnable对象。

三、使用moveToThread (推荐)

使用moveToThread(),因为在Qt4.3(包括)之前,run 是纯虚函数,QThread不能创建对象,必须子类化QThread实现run函数。而从Qt4.4开始run() 默认调用 QThread::exec() ,线程在调用quit()、exit()或terminat()之前不会退出。这样一来不需要子类化 QThread 了,只需要子类化一个 QObject 就够了,这正是被 Bradley T. Hughes(Qt的开发人员)推荐的方法。worker的成员函数和变量不能在主线程调用,但是可以用信号和槽。

可以把多个对象移入某个线程。设计服务器代码时,如果一个客户端一个线程,资源浪费,可以几个客户端公用一个线程

serial_subThread->exit();  //关闭线程
serial_subThread->wait(); //等待线程关闭 this->deleteLater(); //由于移入线程的对象不能指定父对象,所以要手动删除

四、使用QtConcurrent::run

void printMes(char*mes)
{
cout<<"pprintMes(char*mes) thread : "<<QThread::currentThreadId()<<endl; cout<<mes<<endl;
} int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cout<<"mainthread :"<<QThread::currentThreadId()<<endl;
char *mes= "hello world";
QtConcurrent::run(printMes,mes);
returna.exec();
}

Qt -------- 多线程编程的更多相关文章

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

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

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

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

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

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

  4. Qt多线程编程总结(一)

    http://blog.csdn.net/mznewfacer/article/details/6965799 QMutex类 一个线程可以锁定互斥量,并且在它锁定之后,其它线程就不能再锁定这个互斥量 ...

  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. Memcache的客户端连接系列(一) Java

    声明:本文并非原创,转自华为云帮助中心的分布式缓存服务(Memcached)的用户指南. 关键词: Memcached  客户端 Java Java连接池 Java客户端示例 用户的弹性云服务器已安装 ...

  2. java poi技术读取到数据库

    https://www.cnblogs.com/hongten/p/java_poi_excel.html java的poi技术读取Excel数据到MySQL 这篇blog是介绍java中的poi技术 ...

  3. 编译安装hadoop2.6.3

    一.安装环境 1.1  JAVA  安装java1.7 下载jdk1.7: [root@node1~]# wget http://download.oracle.com/otn-pub/java/jd ...

  4. iconFont 阿里巴巴矢量图标使用方法

    挑选图标的过程(共6步) 进入网站:Iconfont网址:http://www.iconfont.cn 点击网站上方的“官方图标库”,选择自己喜欢的图标.在这里我选择天猫的图标库. 选择好自己喜欢的图 ...

  5. 图的遍历——DFS(邻接矩阵)

    递归 + 标记 一个连通图只要DFS一次,即可打印所有的点. #include <iostream> #include <cstdio> #include <cstdli ...

  6. 2017秋软工1 - 本周PSP

    1.本周PSP 2. 本周PSP饼状图 3. 本周进度条 4. 累计进度图

  7. P4编程环境搭建

    本文参照了sdnlab上相关文章的搭建推荐. 使用的系统环境为ubuntu 18.04 组件介绍 主要安装五个组件: BMv2:是一款支持P4编程的软件交换机 p4c:是一款P4的编译器 PI:是P4 ...

  8. Dubbo分享

    1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...

  9. Python实现FTP服务功能

    本文从以下三个方面, 阐述Python如何搭建FTP服务器 一. Python搭建FTP服务器 二. FTP函数释义 三. 查看目录结构 四. 上传下载程序 一. Python搭建FTP服务器 1. ...

  10. Kafka Streams演示程序

    本文从以下六个方面详细介绍Kafka Streams的演示程序: Step 1: 下载代码 Step 2: 启动kafka服务 Step 3: 准备输入topic并启动Kafka生产者 Step 4: ...