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 ...
随机推荐
- vmware centOS上网配置笔记
⦁ 修改/etc/sysconfig/network-scripts/ifcfg-eth0文件 (首先查看本机vmware 虚拟网络编辑器中的网关) 重启网络 使用命令:service net ...
- 概要梳理kafka知识点
主要是梳理一下kafka学习中的一些注意点,按照消息的流动方向进行梳理.详细的kafka介绍推荐看骑着龙的羊的系列博客,具体的某一块的知识点,可以参考我给出的一些参考文章. 1. kafka在系统中的 ...
- 关于wcf服务编译平台是x86, 运行平台是x64时,如何调试
关于调试CTDC项目中的的 wcf服务时注意事项: 因为wcf项目引用的的 x86的程序集,所以wcf生成的目标平台为x86.故在64系统上调试需要执行下面的脚本 具体操作步骤: 1. 必须使用201 ...
- [C++] Class (part 1)
The fundamental ideas behind classes are data abstraction and encapsulation. Data abstraction is a p ...
- 冲刺ing-1
冲刺一 1.第一天的工作分配: 姓名 任务分工 吴伟华(队长) 布置团队任务,发表汇总博客及第一次冲刺博客 蔺皓雯 讨论任务分配 杨池宇 讨论任务分配 鲁婧楠 讨论任务分配 曾茜 讨论任务分配 蔡晨旸 ...
- JAVA mysql数据库 配置
mysql 版本 5.7 数据库连接版本 <!--MySql--><dependency> <groupId>mysql</groupId> <a ...
- 基于gulp的前端自动化开发构建新
关于gulp的使用,已经在之前写过一篇文章,但是遗留了一个问题.问题是实现文件的增量式更新,就是给html引入的js和css文件打上标记.每次更新标记更新. 上篇文章想通过开发同时实现标记的实时更新, ...
- Hadoop出现错误:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable,解决方案
安装Hadoop的时候直接用的bin版本,根据教程安装好之后运行的时候发现出现了:WARN util.NativeCodeLoader: Unable to load native-hadoop li ...
- 使用gdb查看栈帧的情况, 没有ebp
0x7fffffffdb58: 0x004005ba 0x00000000 0x00000000 0x00000000 <-----funcb的栈帧 [0x7fffffffdb60, 0x ...
- [计算机网络] C++模拟telnet登陆SMTP服务发送邮件过程
在百度文库中的<使用telnet协议收发邮件>,我们可以很清楚地看到如何通过telnet来进行发送邮件,下面是一些需要用到的命令,通过以下命令可以很容易实现邮件发送功能.为了更好地理解其中 ...