Qt多线程的几种方式

Qt多线程的几种方式

一、最基本的线程run()

类很简单,cthread.h如下

#include <QThread>
class CThread : public QThread
{
public:
    CThread();
    ~CThread();

    //线程处理函数
    void run();
};

cthread.cpp如下

#include "cthread.h"

CThread::CThread()
{
}

CThread::~CThread()
{
}

void CTread::run()
{
	//do something
}

这种创建线程的方式需要注意
一、只有run()函数是单独在线程里执行。举个栗子CThread类中有另一个成员函数test(),你在别的类中调用test(),它是在主线程中执行的,并非新开的子线程中执行。
二、只有run函数里面创建的对象才会在子线程里执行。举个栗子:你在CTread构造函数里new了一个对象,run里面调用这个对象的业务函数,其实它还是在主线程执行的,你需要在run函数里面new这个对象才可。最典型的列子就是run里面开定时器,你会发现在run函数外new的timer在子线程里面没起到作用。
三、与主线程通信。通信其实指数据交互,Qt已经有很好的connect供我们选择了,能用就用,你会发现少走弯路,而且若与UI交互,connect也是首选。
(12-23号补充)四:线程启动方式忘了写了,一般都是通过调用线程的start()函数启动。直接调用run()函数不可取,结束线程可使用exit(),这个函数可确保线程一定能结束。不过还是注意线程安全相关。
上述创建线程简单粗暴,处理一些简单业务比较方便,但是不够灵活,局限多。

二、moveTothread()

这种创建线程分工明确,2个类:第一个是需要放到线程处理的类(这里就简称业务类),第二个线程类。调用方式也有若干方法,总的思想就是将业务类放到线程类去执行,关键函数就是moveToThread();
手码关键代码如下:

	doWorker* worker = new doWorker();//自己的业务类

	QThread* thread = new QThread();//线程类,直接使用Qt原生即可,注意这里没有父类。

	connect(thread, SIGNAL(started()), worker, SLOT(doSomething())); // 线程开始后执行业务功能函数,

	connect(worker, SIGNAL(finish()), this, SLOT(mainProcessSomething()));// 检查完成。finish()是业务类里面自己定义的信号函数,来告诉主函数部分业务已经处理完成,可以执行其他业务,这里算是交代了如何与主线程交互的办法。

	connect(worker, SIGNAL(finish()), worker, SLOT(deleteLater()));// 执行完成,析构worker

	connect(worker, SIGNAL(destroyed(QObject*)), thread, SLOT(quit()));// 析构worker 完成, 推出线程

	connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); // 推出线程, 析构线程

	worker->moveToThread(thread); // 把worker 移动到线程,这个就是核心函数。将业务类放到线程类。

	thread->start(); // 开始线程,这里会触发start()信号,将启动线程调用我们的业务类成员函数doSomething(),就是上面第一个connect链接;

该说的都在注释里面了,connect这种方式比较好理解而且思路清晰。上面只是简单的示例,具体还需要根据业务逻辑来实现。至于connect的第五个参数在多线程会涉及,而且官方已经很清楚的告诉我们什么情况下使用哪个宏了。如下:

1)Qt::AutoConnection :
(默认)如果接收端位于发出信号的线程中,则使用Qt::DirectConnection。否则,使用Qt::QueuedConnection。Qt会自动识别使用哪个,因为它知道是不是同一个线程。
2)Qt::DirectConnection
信号发出时立即调用槽。这个槽在信号触发的线程中执行。这个就是同一个线程中使用。
3)Qt::QueuedConnection
当控制返回到接收方线程的事件循环时调用槽函数。槽函数在接收方的线程中执行。这个一般在线程与UI数据交互中使用,也是默认值。

上面两种办法应该算是Qt自带线程使用较多的。根据业务需求可能还会使用到线程锁来保护,这里就不介绍了,后面会单独开一个文章记录使用心得。

分享自己的一些使用经验,如果描述不妥的地方还请指出或有其他问题也可留言。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值