线程计数增加了很多,即使删除线程 [英] Thread count increases a lot, even when deleting the threads

查看:208
本文介绍了线程计数增加了很多,即使删除线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个应用程序,我有QOBJects都包含一个QNetworkAccessManager。我知道,建议只有每个应用程序,但是因为我做了更多的6个电话在同一时间,我需要有这样的。所以,这是我如何开始线程。

  FileUploader * fileUploader = new FileUploader(_fileList); 
QThread * fileUploaderThread = new QThread();
fileUploader-> moveToThread(fileUploaderThread);

//上传者>模型
connect(fileUploader,SIGNAL(progressChangedAt(int)),_model,SLOT(reportProgressChanged(int)),Qt :: QueuedConnection);
connect(fileUploader,SIGNAL(statusChangedAt(int)),_model,SLOT(reportStatusChanged(int)),Qt :: QueuedConnection);
// uploader>它的线程
connect(fileUploader,SIGNAL(canceled()),fileUploaderThread,SLOT(quit()),Qt :: QueuedConnection);
connect(fileUploader,SIGNAL(finished()),fileUploaderThread,SLOT(quit()),Qt :: QueuedConnection);
// uploader>这个
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>这个
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 的finished do:

  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的所有回复,我删除,一切似乎被删除,但仍然我抓着我的头,当线程计数不断增加...



编辑:
在我的fileuploader中,我在堆上创建一个对象(管理器),在堆栈上有一个QNetworkAccessManager。当fileuploader被删除时,它在Manager上调用deleteLater(),但它永远不会被删除。我们试图删除管理器并将其设置为NULL,但是给我们一个访问冲突,因为Manager还没有完成(QNetwork.dll报告的问题,所以它必须是在QNAM内运行的东西)。当我们没有获取访问冲突的时候,对象被删除,线程计数恢复正常。什么可以住在QNAM内,并防止我删除它,当它超出范围?我应该在堆上创建QNAM吗?在这个阶段,即使调用deleteLater()...也会调用非析构函数。



此外,如何减少句柄计数?

解决方案

在很多几乎放弃之后,我想出了线程的解决方案。 Synxis对槽的顺序说的是真的。



我仍然有一些问题的文件句柄,如果有人有一个更好的答案,我很高兴接受。



我将代码更改为:

  ... 
// uploader>这个
connect(fileUploader,SIGNAL(canceled()),this,SLOT(deleteFinishedUploader()),Qt :: QueuedConnection);
connect(fileUploader,SIGNAL(finished()),this,SLOT(deleteFinishedUploader()),Qt :: QueuedConnection);
// uploader>它的线程
connect(fileUploader,SIGNAL(destroyed()),fileUploaderThread,SLOT(quit()));

这意味着当对象被删除时,线程被停止(quit这实际上是工作即使文档说明:


此信号是在对象obj被销毁之前立即发出的,不能被阻止。 / p>

此信号发出后,所有对象的子对象都会立即被销毁。


这意味着这个信号在任何东西被破坏之前就被发射了(这意味着我会在上传者被删除之前退出线程)?不是真的够好,它可能是一个更好的方法。但是,atm,我的线程计数在每次上传完成后,并恢复正常后20秒左右(下面几个观察者线程必须被窗口等杀死)。


Have an application where I have QOBJects which all contain an QNetworkAccessManager. I am aware of that it's suggested to only have on per application but since I'm making a lot more that 6 calls at the same time, I needed to have it like this. So, this is how I start the threads.

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++;

Every thread starts out with an index to a list so that they can fetch the thing they need to upload and proceed about 5 steps (calls with the QNetworkAccessManager). When there's no more items to upload, the fileUploader signals "finished()" which calls the deleteFinishedThread and deleteFinishedUploader where I do:

QThread *thread = qobject_cast<QThread*>(sender());

if(thread != NULL) thread->deleteLater();

or

FileUploader *fileUploader = qobject_cast<FileUploader*>(sender());

if(fileUploader != NULL) fileUploader->deleteLater();

These are suppose to delete the threads when they are done.

The issue is that every time I start (for example) 3 threads that have 1 file to upload and handle each, the thread count gets increased by 8-10. This means that the thread count goes from about 5 to 100 if I restart the uploading process a few times.

What am I doing wrong? Or is my biggest issue that I use "Windows Task Manager" to control this? I am handeling all replies from the QNAM which I delete and everything seems to get deleted, but still I scratching my head when the threadcount keeps increasing...

EDIT: In my fileuploader I create an object(Manager) on the heap which has a QNetworkAccessManager on the stack. When the fileuploader gets deleted it calls "deleteLater()" on the Manager but it never gets deleted. We tried to delete the Manager and set it to NULL but that gave us an access violation since the Manager wasn't done yet (the QNetwork.dll reported the issue so it must be something inside the QNAM that is running still). The times when we didnt get access violation, the object was deleted and the thread count went back to normal. What can live inside the QNAM and prevent me from deleting it when it goes out of scope? Should I create the QNAM on the heap instead? At this stage non of the destructors are being called even when calling deleteLater()...

Also, how do I reduce the handle-count?

解决方案

After a lot of "almost giving up" I came up with a solution for the threads. It is true what Synxis said about the order of the slots.

I still however have some issue with the filehandles, and if someone has a better answer that mine I'm happy to accept that.

I changed my code to:

...
// uploader > this
connect(fileUploader, SIGNAL(canceled()), this, SLOT(deleteFinishedUploader()), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(finished()), this, SLOT(deleteFinishedUploader()), Qt::QueuedConnection);
// uploader > its thread
connect(fileUploader, SIGNAL(destroyed()), fileUploaderThread, SLOT(quit()));

This means that the thread gets stopped (quit()) when the object is getting deleted. This actually works even though the documentation states:

This signal is emitted immediately before the object obj is destroyed, and can not be blocked.

All the objects's children are destroyed immediately after this signal is emitted.

Which means that this signals gets emitted just BEFORE anything gets destroyed (which would mean that I would quit the thread before the uploader in it got deleted)? Not really good enough and it might be a better way. HOWEVER, atm, my thread count goes down quite a bit every time the uploader finishes and back to normal after a 20sec or so (a few "watcher-threads" must be killed by windows etc).

这篇关于线程计数增加了很多,即使删除线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆