Qt中一个socket对象只能在同一个线程使用

Qt在不同线程使用socket报错:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpServer(0x1538a748), parent’s thread is QThread(0x15380578), current thread is QThread(0x15388d20)

测试方法

1、创建一个新的类CSocketTest,继承QObject;
2、创建一个QThread的对象;
3、创建一个QTcpServer的对象;
4、在初始化函数中,调用new QTcpServer,然后在connect的槽函数中调用new QTcpServer(子线程);

测试代码

CSocketTest的头文件

包含头文件:
QThread
QTcpServer

定义变量:
private:
QThread m_threadTest;
QTcpServer *m_tcpServer;

定义初始化函数:
void init();

定义信号,槽:
signals:
void notifySocketTest();

public slots:
void onNotifySocketTest();

CSocketTest的cpp文件

构造函数,使用moveToThread关联类与线程
CSocketTest::CSocketTest(QObject *parent) : QObject(parent)
{
m_threadTest.setObjectName(“socketThread”);
moveToThread(&m_threadTest);
}

void CSocketTest::init()
{
m_threadTest.start();
connect(this,SIGNAL(notifyScreenShot()),this,SLOT(SlotLaunchScreenShot()),Qt::QueuedConnection);
qDebug()<<"======= SlotLaunchScreenShot init : "<

#if 0
m_tcpServer = new QTcpServer();
#endif

emit notifyScreenShot();

}

void CSocketTest::SlotLaunchScreenShot()
{
#if 1
m_tcpServer = new QTcpServer();
#endif

int port = 8888; //获得端口号
if(!m_tcpServer->listen(QHostAddress::Any, port))
{
qDebug()<<“QT网络通信”, “服务器端监听失败!”;
}

qDebug()<<"======= SlotLaunchScreenShot m_tcpServer : "< }

在main函数中调用这个init函数
#include “csockettest.h”
int main(int argc, char *argv[])
{
qDebug()<<"======= SlotLaunchScreenShot main : "< CSocketTest::getInstance().init(); //其中CSocketTest::getInstance()是使用单例创建类的对象
return 0;
}

以上两个#if #endif,
第一种情况:是在主线程中new QTcpServer(),第二种情况:是在子线程中用new QTcpServer();

若是第一种情况,此时在子线程又用到了这个这个socket对象,如果是再主线程new的socket对象,则会报上面那个错误,该错误不会影响整个程序运行,但是不能正常使用socket对象。

若是第二种情况,则可以正常使用该socket对象。

说明:若是new socket对象在主线程,使用socket对象也在主线程,也可以正常使用该socket;

结论:在Qt中一个socket对象,只能在同一个线程中new以及使用;若是跨线程使用了socket对象,则无法正常使用该socket对象

同理,经实测在同一个线程创建的变量也只能在当前线程使用。在实际运用中,切记不可跨线程去使用其他线程里面的变量等。若业务需求必须要使用其他线程的数据,可通过信号槽 将该数据emit出去,由其他线程接收再进行使用

你可能感兴趣的:(Qt,调试经验,Qt,跨线程访问变量)