March 20, 2011

SineaNT SineaNT
Lab Rat
7 posts

Multithreaded server

 

Hello

I’m building(or at least trying) a server side app with Qt and i’m a bit stuck with the threads. I have the folowing classes:

  1. #ifndef CLUSTER_H
  2. #define CLUSTER_H
  3.  
  4. #include <QObject>
  5. #include <QMutex>
  6. #include "thread.h"
  7.  
  8. class Cluster : public QObject
  9. {
  10.     Q_OBJECT
  11. public:
  12.     Cluster(QObject *parent = 0);
  13.     QList<Thread*> threads;
  14. signals:
  15.  
  16. public slots:
  17.     void onTimer();
  18.     void garbageCollect();
  19.  
  20. };
  21.  
  22. #endif // CLUSTER_H

  1. #include "cluster.h"
  2. #include "thread.h"
  3. #include <QTimer>
  4. #include "qdebug.h"
  5.  
  6. Cluster::Cluster(QObject *parent) : QObject(parent)
  7. {
  8.  
  9.     QTimer * timer = new QTimer();
  10.     timer->setInterval(1);
  11.     connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
  12.     timer->start();
  13.  
  14.     QTimer * gc = new QTimer();
  15.     gc->setInterval(10);
  16.     connect(gc, SIGNAL(timeout()), this, SLOT(garbageCollect()));
  17.     gc->start();
  18. }
  19.  
  20. void Cluster::onTimer()
  21. {
  22.     threads.append( new Thread() );
  23.     threads[threads.count()-1]->start();
  24.     qDebug() << "Cluster has " << threads.count();
  25. }
  26.  
  27. void Cluster::garbageCollect()
  28. {
  29.     for(int i = 0; i < threads.count(); i++)
  30.     {
  31.         if(threads[i]->isFinished())
  32.         {
  33.             delete threads.takeAt(i);
  34.             garbageCollect();
  35.             break;
  36.         }
  37.     }
  38. }

  1. #ifndef THREAD_H
  2. #define THREAD_H
  3.  
  4. #include <QObject>
  5. #include <QThread>
  6. #include <QTimer>
  7.  
  8. class Thread : public QThread
  9. {
  10.     Q_OBJECT
  11. public:
  12.     Thread(QObject *parent = 0);
  13.     ~Thread();
  14.     void run();
  15.     QTimer * timer;
  16.  
  17. signals:
  18.  
  19. public slots:
  20.     void onTimer();
  21.     void init();
  22.  
  23. };
  24.  
  25. #endif // THREAD_H

  1. #include "thread.h"
  2. #include "QTimer"
  3. #include "qdebug.h"
  4.  
  5. Thread::Thread(QObject *parent)
  6. {
  7. }
  8.  
  9. Thread::~Thread()
  10. {
  11.     timer->stop();
  12.     disconnect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
  13.     delete timer;
  14. }
  15.  
  16. void Thread::run()
  17. {
  18.     QTimer::singleShot(10, this, SLOT(init()));
  19.     exec();
  20. }
  21.  
  22. void Thread::init()
  23. {
  24.     timer = new QTimer(this);
  25.     timer->setInterval(1);
  26.     connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
  27.     timer->start();
  28. }
  29.  
  30. void Thread::onTimer()
  31. {
  32.     this->quit();
  33. }

The above code is just a simplified version.

My problem is that although i delete the threads, and in the Thread destructor i stop, disconect and delete the timer it still builds up memory, if i don’t use the timer it stays at the same memory usage.

Any ideas of how i should corectly delete the per thread timer ? Or any other objects used by each thread(i will have QSslSockets and others)

2 replies

March 20, 2011

peppe peppe
Ant Farmer
1026 posts

Don’t add slots to QThread subclasses.

http://developer.qt.nokia.com/wiki/Threads_Events_QObjects

 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

March 20, 2011

SineaNT SineaNT
Lab Rat
7 posts

Thanks mate, worked like a charm.

For anyone having the same problem in the future, this is how i solved the problem:

I made a class that made all the work(wich “lives” in the thread) and then run method of the class looks like

  1. void Thread::run()
  2. {
  3.     client = new Wrapped();
  4.     while(client->isAlive)
  5.     {
  6.         sleep(1000); // depending on OS
  7.     }
  8. }

 
  ‹‹ dynamically creating push buttoms based on how many items are needed based on the amount      capture user active window and browser tabs ››

You must log in to post a reply. Not a member yet? Register here!