C++ 通过不同的螺纹使用QTCPSocket

C++ 通过不同的螺纹使用QTCPSocket,c++,multithreading,qt,qt5,C++,Multithreading,Qt,Qt5,以下场景: 我在主线程中创建了一些qtcsockets,并将对象保存在一个单例中(std::vector及其getter);如果用户按下“StartMeasure”按钮,我将启动一个新线程,以避免GUI中的阻塞行为 在那里,我再次启动n个用于硬件通信的新线程(出于速度原因,需要并行流)->发送/接收某些内容并评估响应。(将getter用于存储在singleton中的QTCPSocket) 线程模型: 如果我这样做,我会得到以下警告: QSocketNotifier: socket notifi

以下场景:

我在主线程中创建了一些
qtcsockets
,并将对象保存在一个单例中(
std::vector
及其getter);如果用户按下“StartMeasure”按钮,我将启动一个新线程,以避免GUI中的阻塞行为

在那里,我再次启动n个用于硬件通信的新线程(出于速度原因,需要并行流)->发送/接收某些内容并评估响应。(将getter用于存储在singleton中的QTCPSocket)

线程模型:

如果我这样做,我会得到以下警告:

QSocketNotifier: socket notifiers cannot be enabled/disabled from another thread
有时会出现这样的错误:

_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
我应该在这里处理线程之间QTCPSocket上的信号吗?或者我如何解决这个问题?(我不想发布代码,因为我只需要一个策略/如何正确操作的提示)


谢谢大家!

要在Qt中实现线程间交互,可以使用以下技术之一

首先,您可以简单地使用
Qt::QueuedConnection
Qt::AutoConnection
属性在单独的线程中连接qobject的信号和插槽。然后,Qt将使用自己的事件循环系统将一个线程中的信号提升到另一个线程中的插槽

其次,您可以使用
Qt::QueuedConnection
Qt::AutoConnection
从一个线程调用
QMetaObject::invokeMethod
。Qt将再次提升该调用,以便在另一个线程中调用

实际上,您不能直接从一个线程调用网络对象(例如,qtcsocket)、qtimer和其他一些使用Qt事件循环系统并存在于其他线程中的方法

更新


只需注意,只有在目标线程中运行
QEventLoop
时,上述方法才适用(不确定,可能对于信号/插槽apptoach,两个线程都必须这样做)
QThread
在默认情况下提供了一个,如果您不在覆盖的
run()
中重新实现
run()
或手动调用
exec()
,则可以使用以下技术之一在Qt中实现线程间交互

首先,您可以简单地使用
Qt::QueuedConnection
Qt::AutoConnection
属性在单独的线程中连接qobject的信号和插槽。然后,Qt将使用自己的事件循环系统将一个线程中的信号提升到另一个线程中的插槽

其次,您可以使用
Qt::QueuedConnection
Qt::AutoConnection
从一个线程调用
QMetaObject::invokeMethod
。Qt将再次提升该调用,以便在另一个线程中调用

实际上,您不能直接从一个线程调用网络对象(例如,qtcsocket)、qtimer和其他一些使用Qt事件循环系统并存在于其他线程中的方法

更新


只需注意,只有在目标线程中运行
QEventLoop
时,上述方法才适用(不确定,可能对于信号/插槽apptoach,两个线程都必须这样做)<根据我在一个线程中创建QT套接字并从另一个线程读取/写入它们的经验,如果不在重写的
run()
中重新实现
run()
或手动调用
exec()
,默认情况下,code>QThread会提供一个,因为您可能会遇到多个问题,比如您遇到的问题和崩溃。我建议您在将要使用套接字的线程中实际实例化套接字(调用构造函数)。另一个似乎不好的想法是在一个线程中实例化套接字,然后移动到另一个线程。虽然它通常适用于其他类,但由于某些内部实现,可能是系统实现,这显然不能100%正确地适用于套接字。因此,我遇到了崩溃,尤其是当我尝试异步删除套接字(使用
deleteLater
)和线程同步时,这是由对已删除套接字调用
readyRead
引起的

请考虑在使用线程时更改架构以创建/删除套接字,甚至避免在另一个线程中存储指针(智能的和原始的)(至少不依赖于它们的有效性)。
我希望这些提示将帮助您避免我在套接字和多线程方面所经历的痛苦。

根据我的经验,在一个线程中创建QT套接字,并从另一个线程中读取/写入它们不是一个好主意,因为您可能会遇到多个问题,比如您遇到的问题和崩溃。我建议您在将要使用套接字的线程中实际实例化套接字(调用构造函数)。另一个似乎不好的想法是在一个线程中实例化套接字,然后移动到另一个线程。虽然它通常适用于其他类,但由于某些内部实现,可能是系统实现,这显然不能100%正确地适用于套接字。因此,我遇到了崩溃,尤其是当我尝试异步删除套接字(使用
deleteLater
)和线程同步时,这是由对已删除套接字调用
readyRead
引起的

请考虑在使用线程时更改架构以创建/删除套接字,甚至避免在另一个线程中存储指针(智能的和原始的)(至少不依赖于它们的有效性)。
我希望这些提示将帮助您避免我在套接字和多线程方面所经历的痛苦。

首先不使用线程如何-一开始不使用线程怎么办-P