QThread和QTcpSocket

时间:2013-01-08 07:14:44

标签: c++ qt qthread qtcpsocket

当我做一些项目时我犯了严重错误,现在我必须从底部重新编程..我正在编写多线程服务器,它将处理连接,请求等。但是,当我创建新的时使用QThread的基础对象的类,我用QThread-> run()开始线程,而不是QThread-> start()。现在我收到一堆错误。这是情况。 我有服务器,它在每个连接上创建新线程并开始从每个连接的客户端读取数据。当我收到数据时,它发出连接到主GUI类的信号并显示结果OK。它还保存了用于回复消息的套接字句柄。当我从GUI类向socket写入数据时,它说:

QObject:无法为不同线程中的父级创建子级。 (Parent是QNativeSocketEngine(0x23a6c38),父线程是MyThread(0x1fb8670),当前线程是QThread(0x9eb980)

怎么了?

1 个答案:

答案 0 :(得分:1)

我知道QT,但我并不熟悉QT套接字实现本身,但是从你的错误信息的声音和你描述你的设计的方式来看,你的问题与QT无关,而是与线程/套接字架构有关一般来说。多线程应用程序需要仔细考虑智能设计是否有效,并确保您的会话数据等是一致的,并且不会出现并发问题,孤立数据结构等。

它还保存了回复邮件的套接字句柄。当我从GUI类向socket添加数据时,它会说明......:

在不知道您的实现的所有细节的情况下,如果您在线程1中持久化套接字句柄以响应线程1中的调用,然后尝试使用线程2从调用中向其写入数据,那么原始套接字句柄是在线程2的上下文中无效。这可以解释您的错误消息。

持久的套接字句柄用于后续调用并不是出于各种原因(包括您遇到的问题)做事的好方法。为什么要这样做?如果需要在调用之间保留客户端信息,请使用会话结构来保留该数据。如果你想在对话来回继续时让整个线程保持活跃,设计你的线程/套接字交互以表现那种方式并考虑一个线程池等等。但你不应该只是挂着孤立的套接字 - 每个都必须存在于它自己的线程上下文,并且在其“主”线程之外​​没有有效的句柄。

当一个套接字完成其对话时,产生的线程和在该线程中创建的套接字继续进行对话完成 - 应该全部清除。

如果我理解您的实施正确,我的建议应该可以解决您的问题。

在评论中提到:

“套接字作为全局变量” - 如果我正确理解您正在做什么,则不应该以这种方式使用全局套接字。

您的服务器应用程序应该有一个主线程,其中包含一个侦听请求的持久套接字,当您收到请求时,应该发出一个信号,该信号的插槽应该生成一个初始化新套接字的线程以便处理那个要求。处理线程中的请求,然后清理所有内容等。

如果您需要从传入请求中提取信息并将其保留在某个地方,请在主线程中执行此操作,其他线程应该无法访问您在主线程中为该会话保留的结构(除非您使用同步机制)同样的事情,如果你想在完成后从请求处理中获取信息 - 通过线程终止时发出的信号将它从生成的线程中恢复到主线程中。

如果您不遵守这些规则,则需要使用同步对象,否则您将遇到各种问题,包括您遇到的问题,从错误消息的声音判断。

简而言之:“线程中会发生什么,留在线程中”