2013-01-08 40 views
0

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

的QObject:不能为父母是在不同的线程创建的儿童。 (Parent是QNativeSocketEngine(0x23a6c38),父母的线程MyThread的(0x1fb8670),当前线程的QThread(0x9eb980)

怎么了?

+1

无法启动与运行方法的线程。如果你使用run方法,你没有启动线程,你只需在当前线程上下文中调用常规方法。看看线程财富服务器http://doc.qt.digia.com/qt/network-threadedfortuneserver.html它可能是有帮助的 –

+0

如果你正在使用Qt 4,'QThread'文件不幸是误导和过时的,应该几年前已更新。幸运的是,他们最终提供了[更准确的文档](http://qt-project.org/doc/qt-5.0/qtcore/qthread.html#details)以及Qt5,我强烈建议阅读它,因为它也适用于Qt 4. Kamil Klimek链接的threadedfortuneserver示例已经遵循Qt 5准则。 –

+0

然后,我应该检查线程财富服务器深入了解流程如何工作。这对我来说很难,但我会试一试。谢谢。 – Nika

回答

1

我知道QT,但我并不十分熟悉的QT插座实现本身, 但是从你的错误消息的声音和你描述你的设计的方式,你的问题是不相关的QT但线程/插槽架构一般。多线程应用程序requiew仔细考虑智能设计的效率和确保会议数据等是一致的,而不是与并发问题,孤立的数据结构等等充满

它还保存用于回复消息的套接字句柄。当我写数据从GUI类插座,它说,这...:

不知道你实现所有的细节,如果你坚持的套接字句柄的线程1到线程1的号召,然后尝试从使用线程2的调用向它写入数据,原始套接字句柄在线程2的上下文中无效。这可能会解释您的错误消息。

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

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

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

在你的评论提到:

“插座作为一个全局变量” -你不应该使用一个全球性的插座以这样的方式,如果我理解正确的话,你在做什么。

您的服务器的应用程序应该有一个持久套接字监听请求,主线程,当你得到一个请求进来应该发出的信号,并为信号应产卵初始化一个新的插座螺纹槽处理该请求。在线程中处理请求,然后清理所有内容等。

如果您需要从传入的请求中提取信息并将其保存在某处,请在主线程中执行此操作,而其他线程应该无权访问用于在主线程中保留该会话的结构(除非使用同步机制)如果您希望在完成请求处理时从信息中获取信息 - 通过线程终止时发出的信号将其从衍生线程退回到主线程中,这一点同样重要。

如果不遵循这些规则,你需要使用同步对象或你有各种各样的问题,包括您遇到什么,从你的错误消息的声音判断。

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

+0

嗨,主要问题是我是Qt的新手,我甚至不明白我在做什么有时。现在想象下面的事情。我有QTcpSocket *套接字作为全局变量,可以从任何类访问,并将有相同的结果。当新的连接到达时,socket =新的连接套接字。当我试图将数据从另一个类写入此套接字时,它只是给了我这个错误。 – Nika

+0

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

+0

您的服务器应用程序应该有一个主线程和一个持久套接字来侦听请求,当您收到一个请求时应该发出一个信号,并且该信号的槽应该产生一个线程来初始化一个新的套接字以处理该请求。在线程中处理请求,然后清理所有内容等。 – Vector