Количество потоков значительно увеличивается, даже при удалении потоков.

Есть приложение, в котором у меня есть 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 сигнализирует «завершено ()», что вызывает 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, которые я удаляю, и все, кажется, удаляется, но все же я ломаю голову, когда количество потоков продолжает увеличиваться...

РЕДАКТИРОВАТЬ:В моем загрузчике файлов я создаю объект(Manager)в куче, который имеет QNetworkAccessManager в стеке. Когда загрузчик файлов удаляется, он вызывает «deleteLater()» в диспетчере, но никогда не удаляется. Мы попытались удалить диспетчер и установить для него значение NULL, но это привело к нарушению прав доступа, поскольку диспетчер еще не был выполнен (QNetwork.dll сообщил о проблеме, поэтому это должно быть что-то внутри QNAM, которое все еще работает).Времена, когда мы не получали нарушение прав доступа, объект удалялся и количество потоков возвращалось к норме. Что может жить внутри QNAM и мешать мне удалить его, когда он выходит за рамки? Должен ли я вместо этого создать QNAM в куче? На данном этапе ни один из деструкторов не вызывается даже при вызове deleteLater()...

Кроме того, как уменьшить число дескрипторов-?

13
задан chikuba 17 April 2012 в 04:59
поделиться