在连接初始化后,将QTcpSocket移动到新线程中

8
我有一个线程服务器。
需要在需要运行的线程上创建QTcpSocket,例如:Qt - Handle QTcpSocket in a new thread 通过传递套接字描述符。
我的问题是,我需要拥有一个线程池,并在客户端发送特定令牌后将套接字移动到特定线程上。
换句话说,我需要读取套接字以便预先知道在哪个线程上放置它。
一些想法是首先绑定到一个QTcpSocket,然后读取,然后将描述符发送到线程并创建另一个QTcpSocket,但文档说:

注意:不可能使用同一本地套接字描述符初始化两个抽象套接字。

另一个解决方案是在单独的线程中创建套接字,然后将两个线程合并在一起,尽管我不知道这是否可行。
或者也许能够在调用子线程的setSocketDescriptor之前在主线程上读取套接字描述符,如果这是可能的?

1
出于好奇,为什么您需要让客户端告诉您在哪个线程上运行您的QTcpSocket - Mike
特定令牌定义了套接字需要在哪个线程上运行。我想知道如何指定套接字所需的线程。据我所知,在创建线程时无法指定线程ID。如果您想指定线程名称,只需调用thread->setObjectName("Name"),这与套接字无关。 - rightaway717
为什么不直接使用socket->moveToThread(otherthread)呢? - λuser
码头显示不允许。 - Damien
您可以将其视为用户群集的服务器。用户可以创建一个群集或加入现有群集。每个群集都有自己的线程来提高性能并使用多核心。 - Damien
1个回答

2
您可以轻松地将套接字移动到不同的QThreads中,只需注意以下四点:
1)在移动之前,请确保您的QTcpSocket没有父对象
2)在移动之前,请断开与套接字对象的所有连接
3)在运行于目标线程中的函数中重新连接您需要的任何内容(您可以使用某种池在线程中存储那些“移动”的对象,以便线程拾取它们)
4)在初始化后调用readAll(),因为您可能会错过一些readyRead()信号
如果符合设计要求,我认为没有理由不这样做,至少我曾多次将其用于多线程服务,以便将套接字处理程序分配到不同的核心上。

1
在写入数据时,您将收到来自QIODevice的警告。这是因为并非所有QTcpSocket字段都可以在线程之间移动。 - Dmitry Sazonov
1
我会尽力找到更多信息,因为我无法访问代码库。但是有一个警告:"QSocketNotifier:无法从另一个线程启用套接字通知器"。 - Dmitry Sazonov
2
没有必要进行任何断开连接的操作 - 那只是愚蠢的。其他点都是有效的。QTcpSocket 绝对可以在线程之间移动,至少在 OS X 和 Windows 上,我经常这样做,而且它只是工作正常。套接字可能有一个父对象,然后您必须取消其父对象(例如通过将其设置为瞬态对象的父对象)才能切换线程。 - Kuba hasn't forgotten Monica
1
这并不是很重要,首先,Fortune Server示例已经非常古老,并且在Qt中使用了许多年,所以将QTcpSocket传递进去是完全可以的。 - evilruff
1
在QTcpServer文档中,有两个语句:“注意:如果您想将传入的连接作为另一个线程中的新QTcpSocket对象处理,则必须将socketDescriptor传递到另一个线程中,并在那里创建QTcpSocket对象并使用其setSocketDescriptor()方法。”和“返回的QTcpSocket对象不能从另一个线程中使用。如果您想从另一个线程中使用传入的连接,则需要重写incomingConnection()方法。” - Damien
显示剩余16条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接