背景
熟知Qt有两种多线程的方法,
一、继承QThread的run函数;
二、继承于QObject的类,用moveToThread函数转移到一个Thread里。
Qt4.8之前使用继承QThread的run这种方法,Qt4.8之后,Qt官方建议使用第二种方法。
一、继承QThread的run函数
socketInit(); //需要做一些初始化,和数据的处理
qDebug()<<QStringLiteral("run函数线程id")<<QThread::currentThread();
while(m_stoped)//如果需要退出线程就将bRun设置为false.
{
qDebug()<<"run thread ID = "<<QThread::currentThreadId();
msleep(10);//如果不进行休眠会占满cpu,电脑会慢慢变卡.
}
// this->exec();//没加这个的话线程就会结束,并发出Finsh()信号
这边记录下这种方法的几个坑:
1、继承类的创建是在主函数创建的,只有run函数是在另一个线程的
2、对继承的线程创建槽函数,会发现槽函数所在的线程id都是和主线程的id一样
那么如果在run创建一个udp指针,想在槽函数里让udp绑定,则会出现跨线程调用
所以继承run函数想实现外面多线程控制,要使用信号槽来作为传递时不是很好用
二、使用movetothread;
ctludpserver.h
class CtlFlyConnect : public QObject
{
Q_OBJECT
private:
public:
CtlFlyConnect();
~CtlFlyConnect();
signals:
void sigl_threadToView(QString data);
private slots:
void on_threadstart(void);
void on_socketAbort(void);
}
ctludpserver.cpp代码
#include "ctlflyconnet.h"
CtlFlyConnect::CtlFlyConnect( )
{
qDebug()<<QStringLiteral("子线程构造函数id")<<QThread::currentThread();
}
CtlFlyConnect::~CtlFlyConnect()
{
}
void CtlFlyConnect::on_threadstart(void)
{
qDebug()<<QStringLiteral("子线程初始化函数id")<<QThread::currentThread();
//做一些线程初始化函数。一般是指针类的创建
}
void CtlFlyConnect:: on_viewToThread(QString data)
{
qDebug()<<QStringLiteral("子线程槽函数线程id")<<QThread::currentThread();
}
主函数的调用
m_gameSocket = new CtlFlyConnect();
m_GameScokThread = new QThread();
m_gameSocket->moveToThread(m_GameScokThread);
qDebug()<<"mainthread"<<QThread::currentThread();
connect(m_GameScokThread, SIGNAL(started()), m_gameSocket, SLOT(on_threadstart()),Qt::AutoConnection);
m_GameScokThread->start();
connect(this, SIGNAL(sigl_viewToThread(QString)), m_gameSocket, SLOT(on_viewToThread(QString)));
具体的使用步骤如下:
1.从QObject派生一个类,将耗时的工作写在该类的槽函数中。
2.将派生类对象移动到一个QThread中,该线程需要start。(这一步使用moveToThread)
3.通过信号连接派生类的槽函数,并通过信号触发槽函数。(槽函数在子线程中执行)
记录下坑:
1.如果不创建个槽函数来初始化指针变量,而在构造函数里创建的话,创建的指针都是在主线程上;