我可以在属于主线程的 QThread 中使用 waitForReadyRead 吗?

Posted

技术标签:

【中文标题】我可以在属于主线程的 QThread 中使用 waitForReadyRead 吗?【英文标题】:Can I use waitForReadyRead in a QThread that belongs to the mainthread? 【发布时间】:2010-02-26 21:42:20 【问题描述】:

我有一个包含 QUDPsocket 的 QThread(套接字不是 QThread::run() 的本地成员,也许我应该从我正在阅读的内容中更改它)。这个 QThread 在我的 QMainWindow 类中实例化,即 GUI 线程(我没有调用移动到线程)。使用 waitForReadyRead 是否仍然安全,或者我是否绝对需要在 main.cpp 中实例化 QThread 或调用 moveToThread() 以使其成为线程安全的。我在以目前的方式调用 waitForReadyRead 时遇到间歇性双重免费异常(有时我在 3 分钟后几天都没有得到它)​​。

【问题讨论】:

到目前为止似乎没有。您可能可以从 QAction 事件中调用它,但不能形成驻留在主线程中的 QThread。 你在 QThreads 运行方法中调用 waitForBla() 吗? 是的,我确实从那里使用它,但在我使用 moveToThread(this) 之前,QThread 实际上仍然驻留在主线程内,这使得 waitForBla 偶尔会生成一个双释放异常 但我必须承认我还同时进行了另一项更改,那就是在 run 方法而不是类中声明 QUdpSocket,并向其添加父级而不是没有父级。(这是遗留代码) 【参考方案1】:

查看Qt documentation 的QUdpSocket。那里有一条说明该类是可重入的。同样来自Qt documentation:

...如果一个类的成员函数可以从多个线程安全地调用,只要每个线程使用该类的不同实例,则称该类是可重入的。

因此,要回答您的问题,QThread 的父级是什么并不重要,只要您确保您正在使用的 QUdpSocket 实例是在您所在的线程的上下文中实例化的使用它。

【讨论】:

即使将 QUdpSocket 作为 QThread 的类成员,它仍然不足以摆脱它在调用 waitForReadyRead() 时产生的 intemrittent double free exception 在哪里构造QUdpSocket 对象?在线程的构造函数中构造它是不够的,因为构造函数在主线程的上下文中运行。您需要在 run() 方法本身中构造它。

以上是关于我可以在属于主线程的 QThread 中使用 waitForReadyRead 吗?的主要内容,如果未能解决你的问题,请参考以下文章

除了主 ui 线程之外,使用 QThread 设置图形时遇到问题

与主线程在 QThread 中创建的连接对象失败,并且一个 QThread 中的对象之间的连接失败

如何使用 QThread 进行子线程之间的数据传输?

QT多线程及通过事件进行通信(通过自定义事件,然后QApplication::postEvent给主界面,我之前用的是信号槽)

如何在 Qthread 中使用 QAndroidJniEnvironment 指针?

QThread 和 GUI 线程说明