热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Qt中采用多线程实现Socket编程

本文介绍的是Qt中采用多线程Socket编程,由于工作项目的需要,使用Qt的socket编程。Qt里的example是个不错的教程,但

      本文介绍的是Qt中采用多线程Socket编程,由于工作项目的需要,使用Qtsocket编程。Qt里的example是个不错的教程,但是当我把代码移植到多线程的环境时就出问题了:
QObject: Cannot create children for a parent that is in a different thread.

由于想要在线程中保留一个socket,以便维持双边通信,因此定义如下:

SocketThread:public QThread

{

....

private:

QTcpSocket _tcpSocket;

}

但是这段代码并无法正常的完成工作,后来在网上搜了一下资料,找到以下解释(忘了出处了,以下是中文的大概意思):“ 在QThread中定义的所有东西都属于创建该QThread的线程。“

问题出来了,如果按照这个定义,在SocketThread中定义的_tcpSocket,其实是属于mainThread(SocketThread是在main函数中创建),而当我们在SocketThread中的run函数使用到_tcpSocket的时候,其实是跨线程调用,这样就会出现上面的异常。

解决方法: 需要对SocketThread的定义做一下更改:
SocketThread:public QThread  

 ....  
 private:  
 QTcpSocket* _tcpSocket;  
 }  

在上面我们并没有创建具体的对象,而是定义了一个指针,而如何让指针内的内容从属于SocketThread这个线程呢?答案就是要在SocketThread的run方法中初始化  
SocketThread::run()

 ... ;  
 _tcpSocket = new QTcpSocket();  

进行以上修改之后上面的异常就不再出现了。

      但如果在run()函数中,创建_tcpSocket后,进行相应的信号与槽连接,如
    connnect(_tcpSocket, SIGNAL(readyRead), this, SLOT(slot_read());
    this->exec();
    最后进入事件循环;这时,此套接字有可读的消息,则同样的会发生跟上面类似的错误:
QObject: Cannot create children for a parent that is in a different thread.

(Parent is QNativeSocketEngine(0x1f5f9e8), parent's thread is MyThread(0x1f972c8), current thread is QThread(0x717868)
    为解决这个问题,修改连接函数如下:
  connnect(_tcpSocket, SIGNAL(readyRead), this, SLOT(slot_read(), Qt::DirectConnection);
    具体解释,详见手册,
Qt::AutoConnection  (default) Same as DirectConnection, if the emitter and receiver are in the same thread. Same as QueuedConnection, if the emitter and receiver are in different threads.

Qt::QueuedConnection  The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.


推荐阅读
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 添加环境光使正方体显示更真实
    本文介绍了如何给正方体添加环境光以使其显示更真实。通过在代码中加入环境光的计算,可以让物体的背光部分不再完全黑色,从而增加物体的真实感。代码中使用了顶点属性、光照颜色、光照方向、环境光等参数来计算物体的漫反射,并将计算结果与顶点颜色相乘得到最终的颜色。通过调整环境光的参数,可以达到不同的光照效果。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • Introduction(简介)Forbeingapowerfulobject-orientedprogramminglanguage,Cisuseda ... [详细]
author-avatar
小默yic
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有