欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-02 15:41:32
...

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 : "<<QThread::currentThreadId();

#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 : "<<QThread::currentThreadId();
}

在main函数中调用这个init函数
#include “csockettest.h”
int main(int argc, char *argv[])
{
qDebug()<<"======= SlotLaunchScreenShot main : "<<QThread::currentThreadId();
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对象