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


首先要知道,一个线程在资源分配完之后是以某段代码为起点开始执行的,例如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. Apache服务器配置虚拟域名

    我在别处发的帖子 http://www.52pojie.cn/thread-599829-1-1.html

  2. Vue 3 --安装脚手架、过滤器、生命周期的钩子函数、vue-router基本使用

    一.安装脚手架 1.下载node.js,本文下载版本为node-v8.12.0-x64.msi,一键式安装. 2.安装完成后,打开终端,输入node,可进入node环境(两次ctrl+c退出),如下图 ...

  3. 判断文件是否存在 local/hdfs

    在Linux文件系统中,我们可以使用下面的Shell脚本判断某个文件是否存在: # 这里的-f参数判断$file是否存在 if [ ! -f "$file" ]; then ech ...

  4. 约瑟夫问题(vector的使用)

    题目大意:有n个人围坐在圆桌周围,每个人都有一个固定的编号. 从第s(<=n)个人开始报数(按照顺时针方向,从1开始),报到m的人出列,接着再从出列着的 下一个人开始报数(依然从1开始),报到m ...

  5. 最小生成树(prim算法和kruskal算法)

    学习博客:https://www.cnblogs.com/zhangming-blog/p/5414514.html 其实就是加点法:从不属于这个集合的点中找从本集合可以找到的最小边,加入本集合 看代 ...

  6. Git把旧仓库的分支拉到新仓库中

    背景:项目新建了个git仓库(B仓库),放改版的新项目,现在运维所有项目构建都是在一个Jenkins里构建,然后拉镜像到相应服务器里,为了不让运维每次构建不同项目需要改git仓库地址,需要把原来项目仓 ...

  7. Linux利用iptables实现真-全局代理

    对于经常要浏览油管等被墙网站的人而言,利用代理来实现fq是非常有必要的.现在fq的方法中,最为主流的应该要数ssr了,因此本教程都是基于ssr的socks5代理而言的. 在windows中,ssr客户 ...

  8. Java Web项目在Mac系统上启动时提示nodename nor servname provided的解决办法

    今天在Mac系统上启动Java Web项目的时候,提示了Java.net.UnknownHostException: yangxiaomindeMacBook-Pro.local nodename n ...

  9. js和JQuery中offset等属性对比

    HTML: 内容在滚动条下面 <div id="outerDiv"> <div id="myDiv" class="myDiv&qu ...

  10. 《大话设计模式》num01---简单工厂模式

    2017年12月10日 20:13:57 独行侠的守望 阅读数:128更多个人分类: 设计模式编辑版权声明:本文为博主原创文章,转载请注明文章链接. https://blog.csdn.net/xia ...