一、继承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. [译] JavaScript核心指南(JavaScript Core) 【转】

    本文转自:http://remember2015.info/blog/?p=141#scope-chain 零.索引 对象(An Object) 原型链(A Prototype Chain) 构造函数 ...

  2. [Clr via C#读书笔记]Cp9参数

    Cp9参数 可选参数和命名参数 参数设置了默认值(设置要从右到左,有默认值的参数必须放在没有默认值的参数的后面,默认值必须是常量),就可以使用可选参数和命名参数了.向方法传递实参的时候,编译器按照从左 ...

  3. Java学习笔记-10.io流

    1.输入流,只能从中读取数据,而不能向其写出数据.输出流,只能想起写入字节数据,而不能从中读取. 2.InputStream的类型有: ByteArrayInputStream 包含一个内存缓冲区,字 ...

  4. 解析范式(1NF-4NF)

    亲爱的盆友们~又是新的一年,你,准备好新的学习计划了吗~?是读书100本,还是考上5个证?嘛~不管怎么说,角落里那一堆蒙尘的计划表好像在昭示着这仍然是一个充满朝气又艰难的9102年呢!总之,先把#技本 ...

  5. Executor Framework

    Why? look at the following 2 pieces of code for implementing a simple web server based on socket, ca ...

  6. MongoDB3.2 集群搭建

    一.集群的理论知识 1.1 集群成员 MongoDB的集群类似于GreenPlum集群,由一个入口节点负责任务分发与结果统计,分片结节负责执行任务.不同GP,多了一个config servers. 集 ...

  7. 用URL传参带特殊字符,特殊字符丢失

    文章:URL中编码URL特殊字符 文章:用URL传参带特殊字符,特殊字符丢失(encode) 如果url中有特殊字符,需要对url进行编码,否则特殊字符丢失,导致最终接收到的值不对.

  8. SVM之核函数

    SVM之问题形式化 SVM之对偶问题 >>>SVM之核函数 SVM之解决线性不可分 写在SVM之前——凸优化与对偶问题 上一篇SVM之对偶问题中讨论到,SVM最终形式化为以下优化问题 ...

  9. 统计VS2013中有效行数

    将鼠标放在解决方案处,按下ctrl+shift+F b*[^:b#/]+.*$(带前面的using)^b*[^:b#/]+.*$

  10. [计算机网络-应用层] HTTP协议

    1.HTTP概况 Web的应用层协议是超文本传输协议(HTTP),它是Web的核心. HTTP由两部分程序实现:一个客户机程序和一个服务器程序,它们运行在不同的端系统中,通过交换HTTP报文进行对话. ...