首页 > 其他分享 >Qt中Socket跨线程通讯问题

Qt中Socket跨线程通讯问题

时间:2023-04-30 20:14:20浏览次数:41  
标签:SLOT socket MyTcpSocket 线程 connect QTcpSocket Socket Qt

对于一个QTcpServer服务器来说,每当有新客户端连接时,系统会为其分配一个新的QTcpSocket对象进行管理。默认情况下,在incomingConnection函数中创建的QTcpSocket对象将在应用程序主线程中运行,而不是连接所需的处理线程中运行。如果开发者需要确保收到数据的顺序以及避免线程竞争,可以采取以下方式:

1. 将QTcpSocket的派生类(如MyTcpSocket)定义为私有,并提供一个公共的工厂函数 createNewSocket(),在其中设置信号槽并调用QObject::moveToThread(QThread *targetThread)函数将该socket放进指定的线程处理。

void MyThread::incomingConnection(qintptr socketDescriptor)
{
    MyTcpSocket* socket = MyTcpSocket::createNewSocket();
    // 手动断开Qt::AutoConnection机制,信号与动作都在父线程内循环
    QObject::disconnect(socket, 0, 0, 0);

    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
    connect(this, SIGNAL(stop()), socket, SLOT(slotStop()));
    connect(socket, SIGNAL(signalSendData(const QByteArray&)), this, SLOT(slotRecvData(const QByteArray&)));

    socket->setSocketDescriptor(socketDescriptor);
    
    socket->moveToThread(m_thread); // 放进目标线程
}

2.在createNewSocket()函数内部实例化MyTcpSocket对象,在构造函数中设置this->moveToThread(thread)方法,把MyTcpSocket的运行线程设置为指定处理线程。

MyTcpSocket* MyTcpSocket::createNewSocket()
{
    MyTcpSocket *socket = new MyTcpSocket();
    socket->moveToThread(targetThread);

    return socket;
}

MyTcpSocket::MyTcpSocket(QObject *parent)
    : QTcpSocket(parent)
{
    connect(this, SIGNAL(readyRead()), this, SLOT(readData()));
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displayError(QAbstractSocket::SocketError)));
    connect(this, &QTcpSocket::disconnected, this, &QTcpSocket::deleteLater);
}

使用这种方法,可以确保处理m_thread线程的操作发生在MyTcpSocket对象所绑定的线程上,避免了许多线程安全问题和不确定性。

标签:SLOT,socket,MyTcpSocket,线程,connect,QTcpSocket,Socket,Qt
From: https://www.cnblogs.com/david-china/p/17365699.html

相关文章

  • websocket群聊实战
    演示及源码地址:演示地址:https://www.wchime.xyz/#/后端代码:https://gitee.com/mom925/wchime-web-api前端代码:https://gitee.com/mom925/uniapp-web项目说明项目技术:django+mysql+uwsgi+nginx+uniapp逻辑:以django搭建一个webso......
  • Android开发多线程断点续传下载器
    111Android开发多线程断点续传下载器分类: Android 2011-10-0123:14931人阅读 评论(8) 收藏 举报使用多线程断点续传下载器在下载的时候多个线程并发可以占用服务器端更多资源,从而加快下载速度,在下载过程中记录每个线程已拷贝数据的数......
  • Java 网络编程 —— Socket 详解
    构造Socket在【客户端/服务端】的通信模式中,客户端需要主动构造与服务器连接的Socket,构造方法有以下几种重载形式:Socket()Socket(InetAddressaddress,intport)throwsUnknownHostException,IOExceptionSocket(InetAddressaddress,intport,InetAddresslocalAddr,in......
  • Pycharm QT 设置
    Note:QtDesigner还是要用到完整版QT,不然功能不完整.pygram:D:\DeveloperTools\Anaconda\Scripts\pyuic5.exeArguments:$FileName$-o$FileNameWithoutExtension$.pyWorkingdirectory:$FileDir$......
  • 从源码编译并安装LXQT
    平台:ubuntu-22.04-server-amd64.对象:LXQT.文件:lxqt.LXQt是由LXDE-Qt和RazorQt合并的项目,它的目标是创建一个轻量级、模块化、运行快并且简单易用的桌面环境。本例中会介绍多种发行版下的编译方法,本例中使用Ubuntu22.04,你也可以使用其它发行版。1.安装编译环境CMake版本≥3.......
  • pyqt5-QSplitter
    1、介绍QSplitter类是用于分裂器水平布局或垂直布局,效果是该组件内在水平或垂直方向上的直接子组件,可以用鼠标拖动子组件之间的分界线,以变化各自的宽度或长度。简单来说,就是在水平布局或垂直布局的固定分配上,允许各组件变化尺寸。2、类和初始化classQSplitter(QFrame):快速......
  • 线程常用方法join 和threadLocal
     从源码中可以得知,如果想要join方法正常生效,调用join方法的线程对象必须已经调用了start()方法并且未进入终止状态。扩展:从join方法的源码来看,join方法的本质调用的是Object中的wait方法实现线程的阻塞,wait方法的实现原理在后续的文章中在说详细阐述。**但是我们需要知道的是......
  • pyqt5-颜色
    1、颜色选择器col=QColorDialog.getColor()该行代码可以打开一个子窗口,选择颜色选择后可以点击确认或取消,都是返回一个PyQt5.QtGui.QColor对象,而并不会因为点击取消返回None点击确认时,col.name可以获取一个str类型,比如#7bf8ff,col.value都是int类型255点击取消时,col.name可......
  • websocket如何建立
    websocket是什么WebSocket是一种计算机通信协议,它提供了在单个TCP连接上进行全双工通信的能力。它允许客户端和服务器之间进行实时数据交换,可以用于实现在线游戏、聊天室、股票市场等需要实时通信的应用程序。WebSocket协议是HTML5规范的一部分,支持大部分现代浏览器。如何建立......
  • 《asyncio 系列》3. 详解 Socket(阻塞、非阻塞),以及和 asyncio 的搭配
    楔子在前面两篇文章中,我们介绍了协程、任务和事件循环,研究了如何同时运行长耗时的操作,并探索了一些可以优化此操作的asyncioAPI。然而,到目前为止,我们只是用asyncio.sleep函数模拟了长时间的操作。由于我们想要构建的不仅是演示应用程序,因此我们将使用一些真实世界的阻塞操作......