gpt4 book ai didi

multithreading - QNetworkAccessManager 在删除时崩溃

转载 作者:行者123 更新时间:2023-12-01 01:28:27 31 4
gpt4 key购买 nike

我有一个从 QObject 派生的类“下载器”,它在工作线程中运行。当线程启动时,下载器在堆上创建一个 QNetworkAccessManager 对象,并开始请求文件。我会跟踪请求和接收了多少文件。获得所有文件后,我删除 QNetworkAccessManager 对象并退出线程。我的问题是,无论何时何地,删除管理器对象都会导致崩溃。我什至尝试过 manager->deleteLater()。如果我不删除它,我的代码运行良好,但我知道那里存在内存泄漏。这是我的代码的精简版本。

创建下载器和线程,并设置信号以便启动线程开始下载,下载完成后,线程停止:

QThread thread;
Downloader downloader;
downloader.setFiles(files);
downloader.moveToThread(&thread);

downloader.connect(&thread, SIGNAL(started()), SLOT(downloadFiles()));
thread.connect(&downloader, SIGNAL(downloadsFinished()), SLOT(quit()));

thread.start();

下载器的实现:
void Downloader::downloadFiles()
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*)));

receivedCount = 0;
requestCount = files.count();

for (QStringList::const_iterator pos = files.begin(); pos != files.end(); ++pos)
{
QUrl url(*pos);
manager->get(QNetworkRequest(url));
}
}


void Downloader::finished(QNetworkReply *reply)
{
// *** Get the file data and process it *** //

++receivedCount;
reply->deleteLater();

if (receivedCount == requestCount)
{
// manager->deleteLater();
emit downloadsFinished();
}
}

注释掉的行将使应用程序崩溃。即使在 Downloader 的析构函数中删除管理器,或将下载器设置为管理器的父级也会使应用程序崩溃。

我首先尝试将管理器创建为堆栈上的常规成员变量,但这样做会导致它自己的错误,因为管理器将在 GUI 线程中创建,然后尝试在不同的线程上创建子项。

在有人说“QNetworkAccessManager 是异步的。为什么在工作线程中使用它之前?”我有我的理由。做这样的事情不应该是闻所未闻的。

最佳答案

唯一明显的问题在下面,但我不确定您是否已经发布了整个代码

void Downloader::downloadFiles()
{
QNetworkAccessManager *manager = new QNetworkAccessManager();

您正在创建 本地 QNetworkAccessManager *manager在您的方法中,但不保留对它的引用,然后尝试在 finished() 方法中访问它。

您应该分配 new QNetworkAccessManager();一个成员变量!

关于multithreading - QNetworkAccessManager 在删除时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6326237/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com