QThread 采用moveToThread方式实现多线程。 线程本身、connect关联的槽函数、connect关联的lambda对象分别运行在哪个线程中。
Qt如何实现多线程:https://www.cnblogs.com/azbane/p/11372531.html
September 5,2019
先抛出几个问题,用问题来引导思维导向:
1、继承的QObject子类,和QThread对象,是在哪个线程创建的?(即:QObject子类对象和QThread对象的依附线程是哪个?)
2、QThread在哪个线程运行?
3、QObject::moveToThread( QThread )后,QThread 的信号(started/finished)关联的QObject子类对象的函数(槽函数)哪个线程运行?
4、QObject::moveToThread( QThread ) 后,QThread的信号(started/finished)关联的依附线程对象的槽函数在哪个线程运行?
5、信号和槽的新版本,用lambda表达式处理信号的情况(QThread的信号(started/finished)关联的lambda),lambda对象运行在哪个对象?
看起来很复杂,其实并不可怕:想知道对象在哪个线程运行,有两种方式可用
1:QThread::currentThreadId() 返回16进制的线程ID (#include<QThread>)
2:std::this_thread::get_id() 返回10进制的线程ID (#include<iostream> #include <QThread>)
先给答案,再上例子说明, 最后给出遇到的错误情况。
上面跑出的5个问题的答案:
假定QObject子类对象和QThread对象都是在线程A中创建。
1、线程A。 调用std::this_thread::get_id
2、线程A。 调用QThread::currentThreadId, 需要由16进制转成10进制,再对比。
3、线程B。 假定线程id = B 。调用std::this_thread::get_id
4、线程A。 调用std::this_thread::get_id
5、线程B。 调用std::this_thread::get_id
例子主要信息说明:
类ShapeLayout:
有两个指针数据成员:GenerateGridFileWork * m_generateGridFileWork; QThread * m_generateGridFileWorkThread;
有一个函数成员:MakeGrid, 函数里面创建两个指针数据成员。
m_generateGridFileWork->moveToThread(m_generateGridFileWorkThread);
GenerateGridFileWork::slotsWork
QThread::signals - started / finished
ShapeLayout.h
-----------------------------------------------------------
class ShapeLayout : public QObject
{
Q_OBJECT public:
void makeGrid(); public slots:
void slotsThreadFininshed(); private:
GenerateGridFileWork * m_GenerateGridFileWork = nullptr;
QThread * m_GenerateGridFileWorkThread = nullptr;
} ShapeLayout.cpp
-----------------------------------------------------------
void ShapeLayout::makeGrid()
{
std::cout<<"ShapeLayout thread id is "<<std::this_thread::get_id()<<std::cout; //问题-1
m_GenerateGridFileWork = new GenerateGridFileWork ;
m_GenerateGridFileWorkThread = new QThread; m_GenerateGridFileWork->moveToThread(m_GenerateGridFileWorkThread); QObject::connect(m_GenerateGridFileWorkThread, &QThread::started, m_GenerateGridFileWork , &GenerateGridFileWork::slotsWork); QObject::connect(m_GenerateGridFileWork, &GenerateGridFileWork::signalsWorkFinished, m_GenerateGridFileWorkThread, &QThread::quit); QObject::connect(m_GenerateGridFileWorkThread, &QThread::finished, this, &ShapeLayout::slotsThreadFininshed); QObject::connect(m_GenerateGridFileWorkThread, &QThread::started, []{
std::cout<<"connect thread-started signals lambda object thread id is"<<std::this_thread::get_id()<<std::cout; //问题-5
}); QObject::connect(m_GenerateGridFileWorkThread, &QThread::finished, []{
std::cout<<"connect thread-finishedsignals lambda object thread id is"<<std::this_thread::get_id()<<std::cout;//问题-5
});
std::cout<<"QThread thread id is "<<m_generateGridFileWorkThread->currentThreadId()<<std::cout; //问题-2
m_GenerateGridFileWorkThread->start();
}
void ShapeLayout::slotsThreadFininshed()
{
std::cout<<"connect slots function of the ShapeLayout attributable thread id is"<<std::this_thread::get_id()<<std::cout;//问题-4
}
GenerateGridFileWork.h
------------------------------------------------
class GenerateGridFileWork : public QObject
{
public slots:
void slotsWork(); signals:
void signalsWorkFinished();
} GenerateGridFileWork.cpp
------------------------------------------------
void GenerateGridFileWork::slotsWork()
{
std::cout<<"connect to slots function of QObject subObject thread id is "<<std::this_thread::get_id()<<std::cout;//问题-3 emit signalsWorkFinished();
}
调用ShapeLayout::makeGrid(); 一切都知道啦, 自己去运行一遍吧
OK perfect...
September 5, 2019追加一个问题:
moveToThread的方式实现的线程,作业完成后,针对QObject的子类对象和QThread对象的释放顺序有没有讲究?
QThread 采用moveToThread方式实现多线程。 线程本身、connect关联的槽函数、connect关联的lambda对象分别运行在哪个线程中。的更多相关文章
- 在不开启事件循环的线程中使用QTimer(QThread::run函数自带事件循环,在构造函数里创建线程,是一种很有意思的线程用法) good
引入 QTimer是Qt自带的定时器类,QTimer运行时是依赖于事件循环的,简单来说,在一个不开启事件循环(未调用exec() )的线程中,QTimer是无法使用的.通过分析Qt源码可发现,调用QT ...
- Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理
Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...
- 【QT】跨线程的信号槽(connect函数)
线程的信号槽机制需要开启线程的事件循环机制,即调用QThread::exec()函数开启线程的事件循环. Qt信号-槽连接函数原型如下: bool QObject::connect ( const Q ...
- Qt QThread两种方式的使用:1-继承QThread重写run函数; 2- 继承QObject并moveToThread && 消息和槽在线程和依附线程间的传递
2019年08月18日起笔 方式一:继承QThread重写run函数 MyThread.h ----------------------------------- ... class MyThread ...
- Java基础 继承的方式创建多线程 / 线程模拟模拟火车站开启三个窗口售票
继承的方式创建多线程 笔记: /**继承的方式创建多线程 * 线程的创建方法: * 1.创建一个继承于Thread 的子类 * 2.重写Thread类的run()方法 ,方法内实现此子线程 要完成的功 ...
- Qt 的线程与事件循环——可打印threadid进行观察槽函数到底是在哪个线程里执行,学习moveToThread的使用)
周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...
- 想在子线程里面触发的信号的槽函数在子线程执行,信号槽连接必须使用DirectConnection 方式(即使跨线程,也可以强迫DirectConnection,而不能是AutoConnection)
Qt多线程的实现 1.继承QThread,重新run 2.继承Object,调用moveToThread方法 两种方法各有利弊:主要参考:http://blog.51cto.com/9291927/1 ...
- java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】
Callable接口介绍: Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体. call()方法比 ...
- java 22 - 22 多线程之 匿名内部类的方式实现多线程
首先回顾下之前的匿名内部类: 匿名内部类的格式: new 接口或者接口名(){ 重写方法 }; 本质:是该类或者接口的子类对象 匿名内部类方式使用多线程 1.new Thread(){代码-}.sta ...
随机推荐
- spring的15个经典面试题
总结Spring框架的15个经典面试题. 什么是Spring框架? Spring是一种轻量级框架,旨在提高开发人员的开发效率以及系统的可维护性. 我们一般说的Spring框架就是Spring Fram ...
- Java学习:网络编程总结
Java网络编程总结 一.概述 计算机网络是通过传输介质.通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统.网络编程就就是编写程序使联网的两个(或多个)设备( ...
- ELK学习笔记之ElasticSearch的集群(Cluster),节点(Node),分片(Shard),Indices(索引),replicas(备份)之间关系
[Cluster]集群,一个ES集群由一个或多个节点(Node)组成,每个集群都有一个cluster name作为标识----------------------------------------- ...
- 开源矿工工具箱新增了ETH反抽水工具
开源矿工工具箱新增了ETH反抽水工具 —— 将决定使用Claymore挖ETH时拦截的老外的抽水归谁的权力交给矿工 众所周知,所有的挖矿辅助工具都拦截了老外的Claymore内核挖ETH时的内核开发费 ...
- json串处理2
请求百度地址坐标:http://api.map.baidu.com/location/ip?ak=y0Yb5ZgGK9blTDbR7Dwh9jGtn6X1YE48&coor=bd09ll&am ...
- TinyMCE基础配置
选择器配置 插件配置 工具栏配置 菜单配置 皮肤配置 编辑区宽高配置 编辑区样式配置 隐藏状态栏 选择器配置 选择器就是CSS选择器,它告诉TinyMCE哪个元素是可编辑的. 示例: tinymce. ...
- How to use VideoToolbox to decompress H.264 video stream
来源:http://stackoverflow.com/questions/29525000/how-to-use-videotoolbox-to-decompress-h-264-video-str ...
- nginx之旅(第三篇):代理、正向代理、反向代理、代理的原理、nginx反向代理场景、nginx反向代理配置、nginx反向代理语法
一.代理服务与反向代理 什么是代理服务 代理-代理办理(代理理财.代理收货.代理购物等等). 一般情况下,如果没有特别说明,代理技术默认说的是正向代理技术.关于正向代理的概念如下: 正向代理(forw ...
- Linux从入门到放弃、零基础入门Linux(第一篇):计算机操作系统简介、linux介绍
一.计算机操作系统简介 操作系统的定义: 操作系统是一个用来协调.管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间. 操作系统的内核的定义: 操作系统的内核是一个管理和控制程序,负责 ...
- Python学习日记(四十) Mysql数据库篇 八
Mysql存储过程 存储过程是保存在Mysql上的一个别名(就是一堆SQL语句),使用别名就可以查到结果不用再去写SQL语句.存储过程用于替代程序员写SQL语句. 创建存储过程 delimiter / ...