使用move to thread接口将某个类移动到新线程时,该类中如果有指针成员变量的话,也要把指针成员变量一起移动到新线程内,不然指针的成员变量还在主线程,特别的tcp、tdp等比较耗时的对象。
先移动类的对象,再移动类的指针成员变量。
类指针的初始化在移动到新线程前做就可以。
自己写了一个测试udp发送接收的类。用socket助手向发送数据,用自己的程序接收。来测试udp在多线程下的表现。
this->init();
this->moveToThread(&m_thread);
this->m_receiveSocket->moveToThread(&m_thread);
m_thread.start();
这段代码在一个类的构造函数里面,类中函数udp的socekt指针。
如果不把m_receiveSocket也移动到新线程。就会出现下面的错误:
并且udp只能收到一次数据,其余的全部就收不到了。
移动到新线程后,就是这样的结果。
数据接收正常。下面贴上完整源码。
udpReceiveTest .h:
#pragma once
#include <QObject>
#include <qudpsocket.h>
#include <qthread.h>
class udpReceiveTest : public QObject
{
Q_OBJECT
public:
QThread m_thread;
public:
udpReceiveTest(QObject *parent);
udpReceiveTest(const QString &bindIp, const int port);
~udpReceiveTest();
public:
void slot_readyRead();
void init();
private:
QUdpSocket *m_receiveSocket;
QString m_bindIp;
int m_bindPort;
};
udpReceiveTest.cpp:
#include "udpReceiveTest.h"
#include <qnetworkdatagram.h>
#include <qdebug.h>
udpReceiveTest::udpReceiveTest(QObject *parent)
: QObject(parent)
{
}
udpReceiveTest::udpReceiveTest(const QString &bindIp, const int port)
{
this->m_bindIp = bindIp;
this->m_bindPort = port;
this->init();
this->moveToThread(&m_thread);
this->m_receiveSocket->moveToThread(&m_thread);
m_thread.start();
}
udpReceiveTest::~udpReceiveTest()
{
}
void udpReceiveTest::slot_readyRead()
{
QString data;
while (this->m_receiveSocket->hasPendingDatagrams()) {
QNetworkDatagram datagram = m_receiveSocket->receiveDatagram();
data += datagram.data();
}
qDebug() << "receive data :" << data;
qDebug() << "udp thread id:" << QThread::currentThreadId();
}
void udpReceiveTest::init()
{
this->m_receiveSocket = new QUdpSocket();
this->m_receiveSocket->bind(QHostAddress(m_bindIp), m_bindPort);
connect(this->m_receiveSocket, &QUdpSocket::readyRead, this, &udpReceiveTest::slot_readyRead);
qDebug() << "init thread id is " << QThread::currentThreadId();
}
main.cpp:
#include <QtCore/QCoreApplication>
#include <udpReceiveTest.h>
#include <qthread.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main thread id:" << QThread::currentThreadId();
udpReceiveTest socket(("127.0.0.1"), 21);
return a.exec();
}