QThread使用——关于run和movetoThread的区别
注意:本文停止更新,请优先考虑 Qt 线程基础(QThread、QtConcurrent等) dbzhang800 2011.06.18 QThread 似乎是很难的一个东西,特别是信号和槽,有非常多的人(尽管使用者本人往往不知道)在用不恰当(甚至错误)的方式在使用 QThread,随便用google一搜,就能搜出大量结果出来。无怪乎Qt的开发人员 Bradley T. Hughes 声嘶力竭地喊you are-doing-it-wrong 和众多用户一样,初次看到这个时,感到 Bradley T. Hughes有 些莫名奇妙,小题大作。尽管不舒服,当时还是整理过一篇博客QThread 的使用方法 时间过去3个月,尽管依然没怎么用thread;但今天csdn论坛中有人问到这个问题,想想还是尽我所能整理一下吧。提升自己,方便他人,何乐而不为呢? QThread东西还是比较多的,而且我对底层对象了解有限,仅就一点进行展开(或许是大家最关心的一点):QThread中的slots在那个线程中执行? QThread::runrun 函数是做什么用的?Manual中说的清楚:
原文如下(这段话我们称为定理一吧):
这么短的文字一眼就看完了,可是,这是什么意思呢?又能说明什么问题呢?看段简单代码: class Thread:public QThread 对照前面的定理,run函数中的代码时确定无疑要在次线程中运行的,那么其他的呢?比如 slot 是在次线程还是主线程中运行? 你想说主线程,但又心有不甘,对么? QObject::connect涉及信号槽,我们就躲不过 connect 函数,只是这个函数大家太熟悉。我不好意思再用一堆废话来描述它,但不说又不行,那么折中一下,只看它的最后一个参数吧(为了简单起见,只看它最常用的3个值) 下面的列表,我们暂称为定理二:
同前面一样,这些文字大家都能看懂。但含义呢? 不妨继续拿前面的例子来看,slot 函数是在主线程还是次线程中执行呢? 定理二强调两个概念:发送信号的线程 和 接收者所依附的线程。而 slot 函数属于我们在main中创建的对象 thread,即thread依附于主线程
太绕了?不是么(要彻底理解这几句话,你可能需要看Qt meta-object系统和Qt event系统) 怎么办呢?如果上两节看不懂,就记住下面的话吧(自己总结的,用词上估计会不太准确)。
好了,不再添加更多文字了,看代码,估计咱们都会轻松点 主线程(信号)QThread(槽)这是 Qt Manual 和 例子中普遍采用的方法。 但由于manual没说槽函数是在主线程执行的,所以不少人都认为它应该是在次线程执行了。
/*! 然后看到结果(具体值每次都变,但结论不变) main thread: 0x1a40 from thread slot_main: 0x1a40 thread thread: 0x1a48 看到了吧,槽函数的线程和主线程是一样的! 如果你看过Qt自带的例子,你会发现 QThread 中 slot 和 run 函数共同操作的对象,都会用QMutex锁住。为什么? 因为slot和run处于不同线程,需要线程间的同步! 如果想让槽函数slot在次线程运行(比如它执行耗时的操作,会让主线程死掉),怎么解决呢?
main thread: 0x13c0 这可以工作,但这是 Bradley T. Hughes 强烈批判的用法。推荐的方法后面会给出。 run中信号与QThread中槽
/*! 想看结果么? main thread: 0x15c0
如何解决呢?
推荐的方法千呼万唤始出来。 其实,这个方法太简单,太好用了。定义一个普通的QObject派生类,然后将其对象move到QThread中。使用信号和槽时根本不用考虑多线程的存在。也不用使用QMutex来进行同步,Qt的事件循环会自己自动处理好这个。 /*! 结果:恩,slot确实不在主线程中运行(这么简单不值得欢呼么?) main thread: 0x1a5c 其他
|
转自:http://blog.csdn.net/an505479313/article/details/50351745#t8
QThread使用——关于run和movetoThread的区别的更多相关文章
- Qt线程—QThread的使用--run和movetoThread的用法
Qt使用线程主要有两种方法: 方法一:继承QThread,重写run()的方法 QThread是一个非常便利的跨平台的对平台原生线程的抽象.启动一个线程是很简单的.让我们看一个简短的代码:生成一个在线 ...
- Java Thread 的 run() 与 start() 的区别
Java Thread 的使用 Java Thread 的 run() 与 start() 的区别 Java Thread 的 sleep() 和 wait() 的区别 1. ...
- delphi Syntax check、 build、 run、 compile的区别
delphi Syntax check. build. run. compile的区别 Build是从新编译所有和生成exe有关的文件,无论.pas文件是否修改过,它都会重新生成新的.dcu,并从新 ...
- 多线程-Thread的run()与start()的区别
总结: 1) start: 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码.通过调用Thread类的start()方法来启动一个线程,这 ...
- Java线程Run和Start的区别
先上结论:run只是Thread里面的一个普通方法,start是启动线程的方法.何以见得呢?可以执行下面的代码看看run和start的区别: package com.basic.thread; /** ...
- Thread和Runnable、run和start的区别
多线程可以通过两种方式来创建: 一.通过继承Thread类. 二.通过实现Runnable接口. 那么中两种方式到底有什么区别呢?那种方式更好些呢? 先看看几个简单的Demo: Demo1 publi ...
- Dockerfile 中 RUN, CMD, ENTRYPOINT 的区别
RUN 指令:用于指定 docker build 过程中要运行的命令. 语法格式: RUN <command> 或 RUN ["<executeable>" ...
- Java并发编程:Java Thread 的 run() 与 start() 的区别
1. sleep 和 wait 方法解释 sleep()方法是Thread类里面的,主要的意义就是让当前线程停止执行,让出cpu给其他的线程,但是不会释放对象锁资源以及监控的状态,当指定的时间到了之后 ...
- tensorflow中run和eval的区别(转)
在tensorflow中,eval和run都是获取当前结点的值的一种方式. 在使用eval时,若有一个 t 是Tensor对象,调用t.eval()相当于调用sess.run(t) 一下两段代码等效: ...
随机推荐
- 特殊字符url编码以后再解码后出现错误(¬ , ¢, ¤, £)
Url编码的原内容是 “¬ify_url=xxxx” 经过url编码以后再解码回来 “¬”的部分就变成了“¬” 解决方案:把原文里面待url编码的&符号先替换成 ...
- 注意兼容浮点运算误差 0.7 + 0.1 ==0.8 为false
所以比较 汇总或者计算的时候注意确定精度0.7 + 0.1 ==0.8 换成 Math.abs(0.7 + 0.1 ==0.8)<0.0001参考下
- SpringMVC+MyBatis+Druid使用MySQL8.0.11版本
1.使用MySQL8.0.11版本,要使用5.1.45或其他高版本驱动jar包,我本地使用的是最新的8.0.11 2.更换了MySQL驱动后,报Cannot find class [com.aliba ...
- [daily]在dark theme下,启动wps的方法
dark之后,wps的字体变成了灰白的 这样启动 env GTK2_RC_FILES=/usr/share/themes/Breeze/gtk-2.0/gtkrc /usr/bin/et -style ...
- Spring mvc下Ajax获取JSON对象问题 406错误
spring 通过@ResponseBody标签返回JSON数据的方法都报406错: Failed to load resource: the server responded with a stat ...
- NuGet Install-Package报错解决Package Manager Console error - PowerShell version 2.0 is not supported. Please upgrade PowerShell to 3.0 or greater and restart Visual Studio.
问题: Package Manager Console error - PowerShell version 2.0 is not supported. Please upgrade PowerShe ...
- rosetta geometric constraint file(用于match和design)
cst(constraint file)文件示例: CST::BEGIN TEMPLATE:: ATOM_MAP: atom_name: C6 O4 O2 TEMPLATE:: ATOM_MAP: r ...
- tensorflow输出
在Session对象上调用run()函数,执行流图,即可得到输出, 可获取单个输出,也可获取多个输出 import tensorflow as tf import numpy as np consta ...
- Eclipse安装svn插件的几种方式(转)
1.在线安装: (1).点击 Help --> Install New Software... (2).在弹出的窗口中点击add按钮,输入Name(任意)和Location(插件的URL),点击 ...
- Spring Boot中JSON参数传递,后台实体接受问题
1.json参数为json字符串 var data = { name: '超管不是11', password: '123456' }; $.ajax({ type:"post", ...