有一个应用程序,其中我有 QOBJects,它们都包含一个 QNetworkAccessManager。我知道建议只对每个应用程序进行一次调用,但由于我同时进行了 6 次以上的调用,因此我需要这样。所以,这就是我启动线程的方式。
FileUploader *fileUploader = new FileUploader(_fileList);
QThread *fileUploaderThread = new QThread();
fileUploader->moveToThread(fileUploaderThread);
// uploader > model
connect(fileUploader, SIGNAL(progressChangedAt(int)), _model, SLOT(reportProgressChanged(int)), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(statusChangedAt(int)), _model, SLOT(reportStatusChanged(int)), Qt::QueuedConnection);
// uploader > its thread
connect(fileUploader, SIGNAL(canceled()), fileUploaderThread, SLOT(quit()), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(finished()), fileUploaderThread, SLOT(quit()), Qt::QueuedConnection);
// uploader > this
connect(fileUploader, SIGNAL(canceled()), this, SLOT(deleteFinishedUploader()), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(finished()), this, SLOT(deleteFinishedUploader()), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(finishedCurrentUpload()), this, SLOT(uploadNextFileOrFinish()), Qt::QueuedConnection);
// thread > this
connect(fileUploaderThread, SIGNAL(finished()), this, SLOT(checkIfAllThreadsAreFinished()), Qt::QueuedConnection);
connect(fileUploaderThread, SIGNAL(finished()), this, SLOT(deleteFinishedThread()), Qt::QueuedConnection);
// this > uploader
connect(this, SIGNAL(cancel()), fileUploader, SLOT(cancel()), Qt::QueuedConnection);
fileUploaderThread->start();
QMetaObject::invokeMethod(fileUploader, "init", Qt::QueuedConnection);
QMetaObject::invokeMethod(fileUploader, "uploadAt", Qt::QueuedConnection, Q_ARG(int, startIndex));
QMutexLocker locker(&_mutex);
_threadCount++;
每个线程都以列表的索引开始,以便他们可以获取他们需要上传的内容并继续执行大约 5 个步骤(使用 QNetworkAccessManager 调用)。当没有更多项目要上传时,fileUploader 会发出“finished()”信号,它会调用我所做的deleteFinishedThread
事情deleteFinishedUploader
:
QThread *thread = qobject_cast<QThread*>(sender());
if(thread != NULL) thread->deleteLater();
或者
FileUploader *fileUploader = qobject_cast<FileUploader*>(sender());
if(fileUploader != NULL) fileUploader->deleteLater();
这些假设在完成后删除线程。
问题是,每次我启动(例如)3 个线程,每个线程都有 1 个文件要上传和处理,线程数会增加 8-10。这意味着如果我重新启动上传过程几次,线程数将从大约 5 变为 100。
我究竟做错了什么?还是我最大的问题是我使用“Windows 任务管理器”来控制它?我正在处理我删除的 QNAM 的所有回复,所有内容似乎都被删除了,但是当线程数不断增加时,我仍然摸不着头脑......
编辑:在我的文件上传器中,我在堆栈上创建了一个对象(管理器),它在堆栈上有一个 QNetworkAccessManager。当文件上传器被删除时,它会在管理器上调用“deleteLater()”,但它永远不会被删除。我们试图删除 Manager 并将其设置为 NULL,但这给了我们访问冲突,因为 Manager 还没有完成(QNetwork.dll 报告了这个问题,所以它必须是 QNAM 内部仍在运行的东西)。当我们没有遇到访问冲突时,对象被删除并且线程数恢复正常。QNAM 中有什么可以阻止我在超出范围时删除它?我应该在堆上创建 QNAM 吗?在这个阶段,即使调用 deleteLater(),也不会调用任何析构函数......
另外,如何减少句柄数?