hi all,

in my application I'd like to split the processing of some of my functions into several threads.

Several "workerthreads" should be processed simultaneously, increasing spead especially on multicore systems, and when accessing databases.

The "workerthreads" should be observerd & managed by a "observerthread".

in general it should look like:

Qt Code:
  1. worker1---
  2. |
  3. worker2-----<--observer---<---maineventLoop
  4. |
  5. worker3---
  6.  
  7. etc.
To copy to clipboard, switch view to plain text mode 

I've already implemented a minimum example, and would like to hear your opinions on how to improve my idea in terms of speed, threadsafety and adaptability.
i'm sure you'll find some glitches , but its the first time i use the qt threading system in an expanded way...


simple main
Qt Code:
  1. #include "QueryThread.h"
  2. #include <QApplication>
  3.  
  4. int main(int argc, char *argv[])
  5. {
  6. QApplication app(argc, argv);
  7. QueryThread ob(2);
  8. ob.start();
  9. return app.exec();
  10. }
To copy to clipboard, switch view to plain text mode 

observer
Qt Code:
  1. #ifndef QUERYTHREAD_H
  2. #define QUERYTHREAD_H
  3.  
  4. #include <QThread>
  5. #include <QList>
  6. #include <QWaitCondition>
  7. #include <QMutex>
  8. #include <WorkerThread.h>
  9.  
  10. class QueryThread : public QThread
  11. {
  12. Q_OBJECT
  13.  
  14. public:
  15. QueryThread(int maxWorkers = 1, QObject *parent = 0) : QThread(parent){
  16. _maxWorkers = maxWorkers;
  17. _currentWorkers = 0;
  18. }
  19. ~QueryThread (void){
  20. for (int i = 0; i < _list.size(); i++){
  21. _list.at(i)->terminate();
  22. _list.at(i)->wait();
  23. delete _list.at(i);
  24. }
  25. _list.clear();
  26. }
  27. void run(){
  28. for (int i = 0; i < 10; i++){
  29. _mutex.lock();
  30. if(_currentWorkers >= _maxWorkers)
  31. _wait.wait(&_mutex);
  32. qDebug("Query %d", i);
  33. createWorker();
  34. _mutex.unlock();
  35. }
  36. }
  37.  
  38. public slots:
  39. void workerThreadFinsihed(int id){
  40. QMutex mutex;
  41. mutex.lock();
  42. _currentWorkers--;
  43. freeList();
  44. _wait.wakeOne();
  45. mutex.unlock();
  46. }
  47.  
  48. signals:
  49. void queryFinished();
  50.  
  51. private:
  52. void createWorker(void){
  53. static int testId = 0;//testid
  54. WorkerThread *work = new WorkerThread(testId++);
  55. _currentWorkers++;
  56. connect(work, SIGNAL(workFinished(int)), this, SLOT(workerThreadFinsihed(int)));
  57. _list.append(work);
  58. work->start();
  59. }
  60. void freeList(void){
  61. for (int i = 0; i < _list.size(); i++){
  62. if (_list.at(i)->isFinished()){
  63. delete _list.at(i);
  64. _list.removeAt(i);
  65. }
  66. }
  67.  
  68. }
  69. QList<WorkerThread*> _list;
  70. QMutex _mutex;
  71. int _maxWorkers;
  72. int _currentWorkers;
  73. };
  74. #endif
To copy to clipboard, switch view to plain text mode 

worker
Qt Code:
  1. #ifndef WORKERTHREAD_H
  2. #define WORKERTHREAD_H
  3.  
  4. #include <QThread>
  5.  
  6. class WorkerThread : public QThread
  7. {
  8. Q_OBJECT
  9.  
  10. public:
  11. WorkerThread(int id = 0, QObject *parent = 0) : QThread(parent){
  12. _id = id;
  13. }
  14. ~WorkerThread(void){qDebug("Worker %d delete", _id);}
  15. void run(){
  16. for (int i = 0; i < 5; i++){
  17. qDebug("Worker %d, iteration %d", _id, i);
  18. sleep(1);
  19. }
  20. emit workFinished(_id);
  21. }
  22. signals:
  23. void workFinished(int id);
  24.  
  25. private:
  26. int _id;
  27. };
  28. #endif
To copy to clipboard, switch view to plain text mode 

regards