我可以在属于主线程的 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 中的对象之间的连接失败
QT多线程及通过事件进行通信(通过自定义事件,然后QApplication::postEvent给主界面,我之前用的是信号槽)