这是一篇随记,排版什么的就没有那么好了:)


首先要知道,一个线程在资源分配完之后是以某段代码为起点开始执行的,例如STL内的std::thread,POSIX下的pthread等,都是以函数加其参数之后在新线程内调用运行的,但是,Qt的却进行了一个封装,要使用Qt的QThread,核心思想就是将对象在线程内创建或移入线程中,之后通过那些在线程内的对象的信号和槽方式与其他线程进行交互,这里就衍生出来了两种写法(虽然核心思想都是一样的):

  • 第一种:
...
class myThread:
public QThread{
private:
myObj1 obj1; //注意,这两个对象都要继承自QObject,
myObj2 obj2; //否则不能使用信号和槽,而且没有moveToThread这个方法
public:
myThread(){
obj1.moveToThread(this);
obj2.moveToThread(this);
}
void run() override{
myObject3 obj3; //此时该对象本省就是线程内的对象了,不需要继承自QObject
//但是缺点在于,要以多线程的方式
//即在当前线程内使用该对象的方法,只能在当前函数内调用
//这实际上是与Qt的开发思想是相悖的,Qt的多线程开发思想就是
//借助信号和槽的机制,以当前线程的槽队列来进行线程内的对象
//与其他线程内交互
...
...
exec(); //进入事件循环等待信号的发出
}
public slots:
void slot1(){
...
}
};
...

其实不难想,QThread的线程入口就是他的run函数,置于其他的,遵从一个原则:


所有的资源(包括信号和槽函数),都是属于创建该对象的那个线程的,所以不难想到在当前myThread中的任何一个信号和槽都将会在默认情况下在创建这个对象的那个线程内执行,比如:

int main(int a,char **b){
QtCoreApplication a(a,b);
QTimer tmer;
myThread mTh;
QObject::connect(&tmer,"timeout()",&mTh,"slot1()");
tmer.start(1s);
return a.exec()
}

很明显,在QTimer触发timeout()信号的时候,槽slot1始终在当前线程(主程)内调用


接下来就要隆重介绍两种主要的信号,槽的连接方式了:


Qt::QueueConnection和Qt::DirectConnection


第一种就是将当前的信号放入槽所属的对象的事件循环队列内


第二种是直接在当前线程内调用槽函数,直接调用自然可以知道,执行槽函数的线程就是当前的信号所属的线程


通常默认情况下,连接方式是Qt:AutoConnection,该方式判断,如果信号和槽所属的是一个线程,那么此时使用Qt::DirectConnection,否则使用Qt::QueueConnection


但是注意:


在上面那个例子中,connect不论以何种方式进行信号槽的调用,都将是在主线程内调用的,援引在之前已经说到了,myThread对象的创建线程就是主线程,所以信号和槽均属于主线程,不存在跨线程的情况

  • 第二种:
...
int main(int a,char **b){
QtCoreApplication a(a,b);
QThread sgThread;
myObj1 obj1;
obj1.moveToThread(&sgThread);
QTimer tmer;
QObject::connect(&tmer,"timeout()",&obj1,...,Qt::DirectConnection);
//此时obj1的槽会被主线程调用
QObject::connect(&tmer,"timeout()",&obj1,...);
//此时默认Queue,所以会在sgThread所创建的那个中调用
tmer.start(1s);
return a.exec();
}
...

实际上,第一种和第二种是一模一样的思路和方法,只是moveToThread的位置不同,但是要注意:moveToThread不是线程安全的,换句话说,moveToThread只能是在当前线程和参数所指线程对象不同的情况下才能正确调用,因此第一种方式和第二种方式是一致的.

Qt之QThread随记的更多相关文章

  1. Qt之QThread(深入理解)

    简述 为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程.对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题. 前面,已 ...

  2. 解析Qt中QThread使用方法

    本文讲述的是在Qt中QThread使用方法,QThread似乎是很难的一个东西,特别是信号和槽,有非常多的人(尽管使用者本人往往不知道)在用不恰当(甚至错误)的方式在使用QThread,随便用goog ...

  3. Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)

    QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...

  4. Qt多线程-QThread

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QThread     本文地址:http://techieliang.com/2 ...

  5. Qt之QThread

    简述 QThread类提供了与系统无关的线程. QThread代表在程序中一个单独的线程控制.线程在run()中开始执行,默认情况下,run()通过调用exec()启动事件循环并在线程里运行一个Qt的 ...

  6. Qt线程—QThread的使用--run和movetoThread的用法

    Qt使用线程主要有两种方法: 方法一:继承QThread,重写run()的方法 QThread是一个非常便利的跨平台的对平台原生线程的抽象.启动一个线程是很简单的.让我们看一个简短的代码:生成一个在线 ...

  7. QT下QThread学习(二)

    学习QThread主要是为了仿照VC下的FTP服务器写个QT版本.不多说,上图. FTP服务器的软件结构在上面的分析中就已经解释了,今天要解决的就是让每一个客户端的处理过程都可以按一个线程来单独跑.先 ...

  8. 【QT】 QThread部分源码浅析

    本文章挑出QThread源码中部分重点代码来说明QThread启动到结束的过程是怎么调度的.其次因为到了Qt4.4版本,Qt的多线程就有所变化,所以本章会以Qt4.0.1和Qt5.6.2版本的源码来进 ...

  9. 【QT】QThread源码浅析

    本章会挑出QThread源码中部分重点代码来说明QThread启动到结束的过程是怎么调度的.其次因为到了Qt4.4版本,Qt的多线程就有所变化,所以本章会以Qt4.0.1和Qt5.6.2版本的源码来进 ...

随机推荐

  1. 关于node中的global,箭头函数的this的一个小问题

    this一直是一个JS中的困扰问题,这次在跑JS精粹的代码的时候顺带发现了Node里面全局变量的问题 var x = 1; var myObj = { x: 2 }; myObj.func = fun ...

  2. Linux系统下强制其他用户下线

    强制其他用户下线命令格式:pkill -kill -t tty 解释: pkill -kill -t 强制其他用户下线命令 tty 强制其他用户下线的TTY 如上强制其他用户下线的命令为: pkill ...

  3. CodeForces - 93B(贪心+vector<pair<int,double> >+double 的精度操作

    题目链接:http://codeforces.com/problemset/problem/93/B B. End of Exams time limit per test 1 second memo ...

  4. ElasticSearch 全文检索— ElasticSearch 核心概念

    ElasticSearch核心概念-Cluster 1)代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是去中心化,字 ...

  5. 新手写AIDL构建失败:...aidl.exe'' finished with non-zero exit value 1

    最近学习aidl,写demo后编译报错,跟着<Android开发艺术探索>以及网上的一些aidl详解博客敲完后一直编译不过,错误日志如下: Process 'command 'C:\Use ...

  6. ORACLE将查询的多条语句拼在一个字段下

    select listagg(字段名,'分隔符') within group (order by 某个字段)

  7. Diary

    2019.1.16 233333333 2018.12.5 猜猜我写了什么? 2018.12.3 maya真是越来粤菜了.. 突然发现cf其实有中文 2018.12.1 说好的今天出成绩呢?.. 咕咕 ...

  8. h5 本地存储

    H5本地存储有两个API,一个是Web Storage,还有一个是Web SQL.不管是哪一个,都是基于JavaScript语言来使用,接下来我就教你怎么使用H5本地存储,本文篇幅较大,JS代码较多, ...

  9. 【Shell脚本学习22】Shell 函数:Shell函数返回值、删除函数、在终端调用函数

    函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高.像其他编程语言一样,Shell 也支持函数.Shell 函数必须先定义后使用. Shell 函数的定义格式如下: f ...

  10. SpringBoot的优缺点

    优点: 1.快速构建项目 2.对主流开发框架的无配置继承 3.项目可独立运行,无须外部依赖Servlet容器 4.提高运行时的应用监控 5.极大地提高了开发.部署效率 6.与云计算的天然集成 缺点: ...