Qt中线程之间、线程与进程之间的通信
前⾔:线程的创建是为了单独执⾏⼀个与主进程没有太⼤关联的任务,⽽且这个任务⽐较耗时。线程可以处理⼀些输⼊没有输出的任务,但是有时要处理需要输出结果到其它线程或者进程的任务,⽐如处理⼤量数据的运算,就需要把计算的结果分时传回给对应的线程或者进程。线程与主进程之间的信号槽机制在主进程中连接,因为线程是在主进程实例化的。信号槽机制的响应不需要⼦线程执⾏run函数。
Qt线程间共享数据主要有两种⽅式:
1)使⽤共享内存。即使⽤⼀个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从⽽达到共享数据的⽬的。
2)使⽤singal/slot机制,把数据从⼀个线程传递到另外⼀个线程。
第⼀种⽅法是普遍的⽅法,第⼆种是QT特有的,下⾯主要介绍singal/slot机制。
线程间singal/slot机制通信的规则:
1) 在线程间使⽤信号槽进⾏通信时,槽参数必须使⽤元数据类型的参数;元数据表⽰QT中已经存在的数据类型。
2) Qt内⽣的元数据类型,如int double QString等;
3) 如果要⽤⾃定义的数据类型,需要在connect之前将其注册(qRegisterMetaType)为元数据类型。
4) 线程间⽤“信号与槽”传递引⽤参数的话,要加const,因为const⽂字常量存在常量区中,⽣命周期与程序⼀样的长。这样可以
避免slot调⽤的时候参数的运⾏期已过⽽使引⽤⽆效。
使⽤⾃定义数据,注册为元数据类型的步骤(在接收⽅使⽤下⾯的步骤):
进程通信方式1. (以⾃定义TextAndNumber类型为例)
2. ⾃定⼀种类型,在这个类型的顶部包含:#include <QMetaType>
3. 在类型定义完成后,加⼊声明:Q_DECLARE_METATYPE(TextAndNumber);
4. 在main()函数中注册这种类型:qRegisterMetaType<TextAndNumber>("TextAndNumber");
5. 如果还希望使⽤这种类型的引⽤,可同样要注册:qRegisterMetaType<TextAndNumber>("TextAndNumber&");
6. 引⽤的声明与其它类型的声明有点不同,如5所⽰,类型和后⾯的字符之间差了&,其它类型的声明是<>⾥⾯的内容和“”之间
的字符是⼀样的。
第⼆个步骤的QMetaType是在发送⽅(发送该数据的线程)中⾃定义,并且声明个定义,由该线程发送包含信息的QMetaType到接收⽅(接收数据的线程)。
QT线程-线程之间、线程-进程之间的通信singal/slot机制例⼦:
QObject::connect(&myThread,SIGNAL(addRes(int)),this,SLOT(showRes(int)));
总结:
1. Qt的信号槽函数只默认⽀持Qt的类型和C++提供的内建的基本类型,⽐如int double float等,根本不⽀持C++的std::string
std::vector ⾃定义的struct类型。所以需要⽤Qt提供的Q_DECLARE_METATYPE和qRegisterMetaType来声明和注册⾃定义的类型和C++的其他类型。
2. 多线程间的信号槽传递,在connect的时候需要以Qt::QueuedConnection的⽅式,不然以Qt::DirectConnection的⽅式接收
者UI线程会很长时间收不到后台线程发出的信号,或者信号直接丢失都是有可能的
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论