社区首页 >问答首页 >如何在使用QThreadPool时执行QObject::moveToThread()?

我正在构建一个小型多线程web服务器。QTcpSockets是在主线程中获取的,然后由QtConcurrent交给QThreadPool,QThreadPool最终处理数据并发送一个答案。

我的问题是,套接字是在主线程中创建并在另一个线程中处理的。当试图写入套接字时,这会导致错误:

代码语言:javascript
代码运行次数:0
复制
socket->write(somedata);

QObject:不能为处于不同线程中的父线程创建子线程。(父线程为QNativeSocketEngine(0x608330),父线程为QThread(0x600630),当前线程为QThread(0x505f60) )。

干净的方法是将套接字对象移动到处理线程,使用

代码语言:javascript
代码运行次数:0
复制
socket->moveToThread(QThread::currentThread()).

但是,这只能在创建对象的线程中调用。此外,套接字将QTcpServer对象作为父对象,因此moveToThread()无论如何都会失败(父对象不能切换线程)。

如何将对象移动到线程池运行的代码中的QThread::currentThread()?或者,如何将其写入所创建线程外部的套接字?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-07-16 09:42:45

扩展QTcpServer,重新实现incomingConnection(int socketDescriptor),并将套接字描述符传递给池中的线程。让QRunnable从描述符创建QTcpSocket并启动事件循环来接收套接字的信号。

票数 4
EN

Stack Overflow用户

发布于 2015-01-01 16:09:24

我也同意,捕获incomingConnection(int)并在工作线程中创建套接字是这里的方法。

但是,您的问题是一个更基本的问题,因此请允许我展示一个解决一般问题的备选方案(将任意QObject移动到线程池中的线程):

主线程中的

  1. :将套接字与任何线程分离:

socket->moveToThread(nullptr);

这将挂起套接字的事件处理。然后将它传递给QtConcurrent.

  • In在线程池上执行的函数,现在可以调用

socket->moveToThread(QThread::currentThread());

这将重新启动事件处理.

如果幸运的话,套接字将使它的套接字通知器再次在辅助线程的事件循环中重新注册,并且您可以从工作器提供连接。

不过,这里有两个重要的警告

  • 您不应该将阻塞任务放在全局线程池(QThreadPool::globalInstance())上。正如函数的名称所示,线程池实例是一个全局资源,所有QtConcurrent用户都共享它,最好情况下阻塞它的工作线程会降低池的容量(因此,吞吐量),在最坏的情况下,您将使用工作线程的事件循环(由于第一点而不使用QTcpSocket的同步API ),您需要调用QThread::currentThread()->exec()来启动它。但是,这是一个阻塞调用,并且对线程池调度程序来说,工作人员看起来很忙,所以它不会交给它更多的任务(即。QRunnables).

如果您实际上想要实现多线程tcp服务器,那么您就需要提交自己的线程池。

票数 1
EN

Stack Overflow用户

发布于 2010-06-26 23:04:03

布拉德利·胡格在Qt实验室上写了一篇关于这个话题的文章,也许这会对你有所帮助!

https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3126145

复制
相关文章
Qt高并发
QThread是一个低级(low-level)类,适合用于显式地构建长期运行的线程。
全栈程序员站长
2022/09/03
1.5K0
【Qt】Qt的线程(两种QThread类的详细使用方式)「建议收藏」
Qt提供QThread类以进行多任务处理。与多任务处理一样,Qt提供的线程可以做到单个线程做不到的事情。例如,网络应用程序中,可以使用线程处理多种连接器。
全栈程序员站长
2022/09/01
10K0
Qt多线程编程之线程池
线程的创建及销毁需要与系统交互,会产生很大的开销。若需要频繁的创建线程建议使用线程池,有线程池维护一定数量的线程,当需要进行多线程运算时将运算函数传递给线程池即可。线程池会根据可用线程进行任务安排。
DeROy
2020/09/10
4.2K0
Qt多线程编程之线程池
QThread的用法
QThread类提供了一个与平台无关的管理线程的方法。一个QThread对象管理一个线程。QThread的执行从run()函数的执行开始,在Qt自带的QThread类中,run()函数通过调用exec()函数来启动事件循环机制,并且在线程内部处理Qt的事件。在Qt中建立线程的主要目的就是为了用线程来处理那些耗时的后台操作,从而让主界面能及时响应用户的请求操作。QThread的使用方法有如下两种:
全栈程序员站长
2022/07/21
9130
QThread的用法
QT学习之如何使用Qthread(moveToThread方法)
通常在程序中需要同时做好几件事情,这时不可避免的会涉及到多线程的学习,QT学习过程中亦是如此,而QT中提供了 QThread,因为涉及到信号与槽,线程的使用也有些变化。在QThread的文档中有两种使用方法。
嵌入式小屋
2022/04/27
4.9K0
QT学习之如何使用Qthread(moveToThread方法)
qtcpsocket多线程_qtcpsocket接收数据
最近在写有关网络传输的项目,使用了Qt封装的QTcpSocket,但是发现很多的跨线程导致死机的问题,也许是我了解的不够深入吧。最开始是自己继承一个线程然后把主线程创建的套接字传递到子线程并且在子线程中写入数据遇到程序崩溃;否决后是考虑到了跨线程访问的问题,QTcpSocket跨线程崩溃说明它只能是在哪个线程创建就只能在哪个线程使用,这样想的话只需要把特别耗时的处理(数据准备操作)放到一个子线程中,然后把待写入数据通过信号槽的形式传递给QTcpSocket所在线程(其实就是主线程)中然后调用QTcpSocket::write()发送,但是这就让主线程在写数据了,如果数据不是很大倒也可以,看个人情况而定;最后决定使用QObject::moveToThread()的方式,因为我要不间断的发送大量的数据所以在一个子线程中操作才是明智的选择,就是把在主线程创建好的QTcpSocket对象通过QObject::moveToThread()放到一个子线程中操作(也就相当于是在子线程创建的),后续的QTcpSocket与主线程之间的操作都是通过信号槽形式进行的。
全栈程序员站长
2022/09/30
1.2K0
qtcpsocket多线程_qtcpsocket接收数据
QObject
说到Qt,你肯定首先想到的就是信号和槽,而这就不得不提到Qobject,这次和大家分享下QObject的相关内容,并对一些内容进行代码说明,方便理解。
用户5908113
2019/12/19
1.2K0
QObject
简化QThread示例代码
QThread官方文档在描述线程内容时,提供了一个线程操作的方法,该方法用在大部分场景下都可以适用,但使用起来略有繁琐,需要创建一个线程执行类Worker和控制类Controller,如下代码:
Qt君
2023/03/17
5640
简化QThread示例代码
Qt多线程编程
我在github仓库里面看到之前遗留的Qt_Demo,把文章相应的工程文件提交到仓库里面去,上次的简易聊天室也同步过去了,以及这篇文章的两个线程Demo。
DeROy
2020/09/01
2.2K0
Qt多线程编程
qt多线程编程实例_lgbt
每个程序启动后拥有的第一个线程称为主线程,即GUI线程。QT中所有的组件类和几个相关的类只能工作在GUI线程,不能工作在次线程,次线程即工作线程,主要负责处理GUI线程卸下的工作。
全栈程序员站长
2022/08/18
1.5K0
Qt线程使用的两种方法
一个QThread实例管理程序中的一个线程。QThread的执行开始于run()。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件循环。   你可以使用QObject::moveToThread()将工作对象移动到线程中使用。
Qt君
2019/07/15
2.8K0
QThread 的使用「建议收藏」
注意看倒数第二个单词,QThread 不等于线程,QThread 是负责管理线程的。 接下来看文档,我们清楚的知道QThread的两种使用方式。
全栈程序员站长
2022/09/01
1.5K0
Qt多线程1:QThread
Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里。 Qt4.8之前都是使用继承QThread的run这种方法,但是Qt4.8之后,Qt官方建议使用第二种方法。两种方法区别不大,用起来都比较方便,但继承QObject的方法更加灵活。这里要记录的是如何正确的创建一个线程,特别是如何正确的退出一个线程。
全栈程序员站长
2022/09/02
2.9K0
Qt 线程中使用socket(勘误)
之前写过两篇关于qt线程中使用socket的文章,昨天有小伙伴看了文章之后和我讨论,然后我发现有一篇文章有问题,今天特地更正一下,误导了之前的小伙伴表示歉意。
用户5908113
2019/09/09
1.5K0
Qt 线程中使用socket(勘误)
Qt线程中使用socket作为客户端通信(二)
Qt使用线程的方式有两种,一种是上次所说的继承QThread重新实现run()函数,在run()函数中一直循环处理;另一种则是继承QObject并使用moveToThread()函数将对象移到子线程中。由于继承QThread方式使用的并不规范,Qt官方强烈建议使用继承QObject的方式。
用户5908113
2019/07/29
3.1K0
QT多线程实战_Qt多线程开发项目
窗口本身就是一个死循环,在这样一个死循环中执行任何耗时的操作,都会导致程序崩溃。所以多线程对于窗口编程而言是必要的。
全栈程序员站长
2022/11/16
1.4K0
QT多线程实战_Qt多线程开发项目
你这样做是错的…(翻译文)
我们广泛使用IRC(网上交谈)与我们自己以及社区进行沟通。我在Freenode网络的Qt频道上闲逛,尽我所能帮助别人。
Qt君
2019/08/20
8610
qt tcpsocket_qt中udp通信
设想有如下场景:若干的客户端与服务器端建立连接,建立连接后,服务器端随机发送字符串给客户端,客户端打印输出。该节案例使用TCP编程。
全栈程序员站长
2022/09/30
9010
【Pyside6】Python多线程实现的选择与QThread的推荐实现方式
因为在网络上,特别是中文互联网上,关于Pyside6多线程的写法,特别是QThread的使用提及比较少,且较多使用不太推荐的写法,这篇博客主要是存下我自己参考的博客,希望对大家也有帮助。
Livinfly
2023/03/16
4.8K0
【Pyside6】Python多线程实现的选择与QThread的推荐实现方式
qtcpsocket断开_2020-05-06 QT子线程使用QTcpSocket连接服务器
分别是:1.继承QThread实现多线程2.继承QObject实现多线程(由于继承QObject的多线程实现方法更加灵活,Qt官方推荐使用该方法实现多线程)。这里将采用第二种方式实现多线程
全栈程序员站长
2022/10/03
1.5K0

相似问题

QObject::moveToThread并在线程内执行成员函数

21

QObject::moveToThread中的移动语义

36

如何在Qt5中检测QObject::moveToThread()失败?

22

带有自定义Qobject的MovetoThread问题

26

如何在使用moveToThread时在PyQt5中正确退出moveToThread

155
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文