当从2个线程发出2个网络请求时,Qt应用程序崩溃
我有一个Qt应用程序,它在启动时从主线程启动两个线程。这两个线程都使用QNetworkAccessManager对象的不同实例发出网络请求。我的程序有50%的时候会崩溃,我不确定哪个线程会崩溃 两个线程之间没有直接发生的数据共享或信令。当某个事件发生时,其中一个线程向主线程发出信号,而主线程又可能向第二个线程发出信号。然而,通过打印日志,我非常确定在发送信号期间不会发生崩溃 两个线程的结构如下所示。除了URL等,线程之间几乎没有任何区别当从2个线程发出2个网络请求时,Qt应用程序崩溃,qt,networking,qthread,qnetworkaccessmanager,Qt,Networking,Qthread,Qnetworkaccessmanager,我有一个Qt应用程序,它在启动时从主线程启动两个线程。这两个线程都使用QNetworkAccessManager对象的不同实例发出网络请求。我的程序有50%的时候会崩溃,我不确定哪个线程会崩溃 两个线程之间没有直接发生的数据共享或信令。当某个事件发生时,其中一个线程向主线程发出信号,而主线程又可能向第二个线程发出信号。然而,通过打印日志,我非常确定在发送信号期间不会发生崩溃 两个线程的结构如下所示。除了URL等,线程之间几乎没有任何区别 MyThread() : QThread() {
MyThread() : QThread() {
moveToThread(this);
}
MyThread()::~MyThread() {
delete m_manager;
delete m_request;
}
MyThread::run() {
m_manager = new QNetworkAccessManager();
m_request = new QNetworkRequest(QUrl("..."));
makeRequest();
exec();
}
MyThread::makeRequest() {
m_reply = m_manager->get(*m_request);
connect(m_reply, SIGNAL(finished()), this, SLOT(processReply()));
// my log line
}
MyThread::processReply() {
if (!m_reply->error()) {
QString data = QString(m_reply->readAll());
emit signalToMainThread(data);
}
m_reply->deleteLater();
exit(0);
}
现在奇怪的是,如果我不启动其中一个线程,程序运行正常,或者至少不会在大约20次调用中崩溃。如果两个线程相继运行,程序不会崩溃。如果我同时启动并运行两个线程,程序只会崩溃大约一半的时间
我从日志中收集到的另一件有趣的事情是,每当程序崩溃时,用注释my log line
标记的行是两个线程最后执行的一行。所以我不知道是哪个线程导致了崩溃。但这让我怀疑QNetworkAccessManager在某种程度上是罪魁祸首
我对撞车的原因一无所知。如果有任何建议或建议,我将不胜感激。提前感谢。首先!首先修复线程
//编辑
根据我自己对这种模式的经验,我知道它可能会导致许多不明确的崩溃。我会从清理这件事开始,因为它可能会理顺一些事情,让发现问题变得清晰。我也不知道如何调用makeRequest
。还有关于QNetworkRequest。它只是一个数据结构,所以您不需要将它放在堆上。堆栈构造就足够了。此外,您还应该记住(或以某种方式保护)不要覆盖m_回复指针。您是否多次调用makeRequest
?如果这样做,则可能会导致在上一个请求完成后删除当前处理的请求
如果调用makeRequest两次会发生什么情况:
我不确定为什么在回复完成时调用出口(0)。如果您使用多个makeRequest调用,则此处也不正确。请记住,QThread是单个线程的接口,而不是线程池。所以,当线程实例仍在运行时,不能再次调用它。另外,如果要在入口点
run()
中创建网络访问管理器,则应在exec()
之后的相同位置将其删除。请记住,exec()
是阻塞的,因此在线程退出之前不会删除对象。在应用程序开发的后期,我确实遇到了这两篇文章(错误的方法和正确的方法)。我的Java背景也帮不上忙,您通常通过扩展线程来执行线程。无论如何,问题似乎在于网络访问管理器本身,而不是线程。我将使用一个简单的代码片段来尝试给定的方法,该代码片段再现了这个问题。请提供您对QNetworkAccessManager的任何细微差别的意见。谢谢