Qt -------- 多线程编程
一、继承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 -------- 多线程编程的更多相关文章
- Qt多线程编程总结(一)(所有GUI对象都是线程不安全的)
Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法. 这个文档是提供给那些对多线程编程有丰富的知识和经验的听众的.推荐阅 ...
- Qt多线程编程中的对象线程与函数执行线程
近来用Qt编写一段多线程的TcpSocket通信程序,被其中Qt中报的几个warning搞晕了,一会儿是说“Cannot create children for a parent that is in ...
- Qt多线程编程总结(二)——QMutex
QMutex类提供的是线程之间的访问顺序化. QMutex的目的是保护一个对象.数据结构或者代码段,所以同一时间只有一个线程可以访问它.(在Java术语中,它和同步关键字“synchronized”很 ...
- Qt多线程编程总结(一)
http://blog.csdn.net/mznewfacer/article/details/6965799 QMutex类 一个线程可以锁定互斥量,并且在它锁定之后,其它线程就不能再锁定这个互斥量 ...
- C++11多线程编程
1. 多线程编程 在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作.这种情况下就需要使用多线程,其中一 ...
- Qt 多线程和网络编程学习
一,Qt多线程类学习 QThread类,开始一个新的线程就是开始执行重新实现QThread::run(),run()是默认现实调用exec(),QThread::start()开始线程的执行,run( ...
- Qt中的多线程编程
http://www.ibm.com/developerworks/cn/linux/l-qt-mthrd/ Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功 ...
- [转] Qt 多线程学习
Qt 多线程学习 转自:http://www.cnblogs.com/IT-BOY/p/3544220.html 最近的项目上用到了关于多线程的知识,自己也比较感兴趣,所以就拿了那本<C++ G ...
- QThread多线程编程经典案例分析
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...
随机推荐
- 【机器学习】多项式回归python实现
[机器学习]多项式回归原理介绍 [机器学习]多项式回归python实现 [机器学习]多项式回归sklearn实现 使用python实现多项式回归,没有使用sklearn等机器学习框架,目的是帮助理解算 ...
- Fluent Python: @property
Fluent Python 9.6节讲到hashable Class, 为了使Vector2d类可散列,有以下条件: (1)实现__hash__方法 (2)实现__eq__方法 (3)让Vector2 ...
- BZOJ 4361 isn 容斥+dp+树状数组
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4361 题意概述: 给出一个长度为N的序列A(A1,A2...AN).如果序列A不是非降的 ...
- “Hello world!”团队第二周贡献分规则+贡献分数分配结果
一.贡献规则制定: (1)基础分:9 , 9 , 8 , 7 , 7 , 7 , 6(按在本次编程中承担模块的重要度制定,某一模块重要度的认定通过组内开会讨论决定) (2)会议分:每人没出勤一次会议记 ...
- 域名加www与不加www不一样结果的解决办法
有些浏览器域名访问加www 与不加www出现的页面不一样.在aj请求的时候也不同.firefox与google新版本的都会自动加上www. 比如 访问haitaohua.com,但aj请求的时候是带w ...
- android入门 — ListView的优化
ListView的运行效率是比较低的,因为在getView()中每次都会将整个布局重新加载一遍,当ListView快速滚动的时候就会成为性能瓶颈. 调用View中的findViewById()方法获取 ...
- 《剑指offer》---顺时针打印矩阵
本文算法使用python3实现 1. 问题1 1.1 题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 ...
- Crash使用参考
整理自man 8 crash 1.简介 Crash工具可以用来分析一个正在运行的内核,也可以用来分析一个内核的crash dump文件,这里说的是内核代码异常产生的crash dump文件,不是应用层 ...
- linux下安装多个jdk版本的切换问题
下载地址: https://www.azul.com/downloads/zulu/ 解压: [root@localhost java]# tar -zxvf /usr/java/zulu8.38.0 ...
- springMVC视图有哪些?-009
html,json,pdf等. springMVC 使用ViewResolver来根据controller中返回的view名关联到具体的view对象. 使用view对象渲染返回值以生成最终的视图,比如 ...