我在做某个项目的时候犯了一个严重的错误,现在我必须从头开始重新编程。我正在编写多线程服务器,它将处理连接、请求等。但是,当我用QThread的基对象创建新类时,我是用QThread->run()而不是QThread->start()启动线程。现在我得到了一堆错误。情况是这样的。我有服务器,它在每个连接上创建新的线程,并开始从每个连接的client.When读取数据。我接收数据,它发出信号,连接到主图形用户界面类并显示结果OK。它还保存了用于回复消息的套接字句柄。当我从GUI类向套接字写入数据时,它会这样说:
QObject:无法为另一个线程中的父级创建子对象。(父线程为QNativeSocketEngine(0x23a6c38),父线程为MyThread(0x1fb8670),当前线程为QThread(0x9eb980) )
怎么了?
发布于 2013-01-08 15:56:46
我知道QT,但对QT套接字实现本身和不是很熟悉,但从您的错误消息和描述设计的方式来看,您的问题与QT无关,而是与线程/套接字体系结构有关。多线程应用程序需要经过仔细的智能设计才能高效,并确保您的会话数据等是一致的,并且不会充满并发问题、孤立的数据结构等
它还保存了用于回复消息的套接字句柄。当我从GUI类向套接字写入数据时,它显示...:
在不知道实现的所有细节的情况下,如果您持久化线程1中的套接字句柄以响应线程1中的调用,然后尝试从使用线程2的调用中向其写入数据,则该原始套接字句柄在线程2的上下文中无效。这可以解释您的错误消息。
出于许多原因(包括您遇到的问题),为后续调用保留套接字句柄不是一种好方法。你干吗要干那种事?如果需要跨调用持久化客户端信息,请使用会话结构来持久化该数据。如果你想在来回对话继续的同时保持整个线程的活动状态,设计你的线程/套接字交互的方式,并考虑线程池等。但是你不应该有孤立的套接字挂在那里-每个套接字必须存在于它自己的线程上下文中,并且在它的“home”线程之外没有有效的句柄。
当一个套接字完成它的会话时,派生的线程和在该线程中创建的用于继续会话的套接字都完成了-它们都应该被清理掉。
如果我正确理解了您的实现,我的建议应该可以解决您的问题。
你在评论中提到的:
"socket as a global variable“-如果我正确理解你在做什么的话,你不应该以这种方式使用全局socket。
你的服务器应用程序应该有一个带有持久套接字的主线程来监听请求,当你收到一个请求时,应该发出一个信号,该信号的插槽应该产生一个线程,该线程初始化一个新的套接字来处理该请求。在线程中处理请求,然后清理所有东西,等等。
如果您需要从传入的请求中提取信息并将其持久化到某个位置,请在主线程中执行此操作,而其他线程不应访问用于在主线程中为该会话持久化的结构(除非您使用同步机制)。同样,如果您想在完成后从请求处理中获取信息,请通过线程终止时发出的信号将其从衍生线程中返回到主线程中。
如果您不遵循这些规则,则需要使用同步对象,否则从错误消息的声音来看,您将遇到各种问题,包括您所遇到的问题。
简而言之:“线程中发生的事情,停留在线程中”
https://stackoverflow.com/questions/14209956
复制相似问题