Results 1 to 14 of 14

Thread: QThread - parallel

  1. #1
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Question QThread - parallel

    Hi,

    I am trying to get an application working that utilizes 4 instances of the same thread. I have another thread called ThreadManager that hands data to each of the 4 threads...

    I am processing folders that contain 4000+ files. I must read and update data in each file. They can all be done simultaneously...without depending on each other.

    My 4 workers each process a file...with the Manager controlling which file is next to be processed and handing it off to the next thread that is waiting...

    Now for the problem. I want to update the GUI as each file is processed. I have signals coming out of each worker that is attached to a unique slot in the Manager. The Manager's slots emit signals that are connected to the main app. No problem except that the GUI lags behind...quite a bit...when using QueuedConnections. I currently have DirectConnections for the worker->manager singals and QueuedConnections from the manager->main. If I use DirectConnection for the manager->main, the app crashes with the first worker signal emitted.

    On another note, when I dispatch a file to a worker, if I DO NOT use a wait() on that worker, the app tends to crash after a few iterations. The only way I seem to be able to get through an entire directory is by calling wait(ULONG_MAX)...any ideas?

    Thanks,
    Sam

  2. #2
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread - parallel

    1. you can not use DirectConnection from thread to gui
    2. is it very important to show to user all of that 4000+ filenames ? Show him just a done percent.
    3. each of your thread must check if user wants to close application, and do break if it is.
    4. if lines above didn't help, show code of your gui, manager and workers without actually processing algorythm (just a comment like "here is actually processing code") to decrease your message in post

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QThread - parallel

    Quote Originally Posted by sgrant327 View Post
    No problem except that the GUI lags behind...quite a bit...
    If you have less than 5 processing units in your machine then the GUI thread will be getting less and less CPU time so it will effectively be working slower.

    On another note, when I dispatch a file to a worker, if I DO NOT use a wait() on that worker, the app tends to crash after a few iterations. The only way I seem to be able to get through an entire directory is by calling wait(ULONG_MAX)...any ideas?
    Can we see the exact code?

    By the way, did you think about using QtConcurrent (QRunnable at least) instead of manually spawned threads?

  4. #4
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread - parallel

    Wysota,

    The machine I am working on has dual quad-Xeon processors, essentially 8 cores.

    I am unable to give you the exact code, but here is a quick synopsis:

    Main:

    1. Create ThreadManager
    2. Connect TM's signals to main's GUI update slots
    3. Pass 'default' settings to TM
    4. Compile list of files in selected directory
    5. Pass list to TM
    6. TM.start();

    ThreadManager:

    1. Create WorkerThread1
    2. Connect WT1's signals to TM's slots
    3. Pass 'default' settings to WT1
    4. Create WorkerThread2
    5. Connect WT2's signalst to TM's slots
    6. Pass 'default' settings to WT2

    --start running:

    Qt Code:
    1. while( !fileIDX == fileList.count() )
    2. {
    3. if( !WT1.isRunning() )
    4. {
    5. WT1.filename = list[fileIDX];
    6. WT1.start();
    7. fileIDX++;
    8. }
    9. if( !WT2.isRunning() )
    10. {
    11. WT2.filename = list[fileIDX];
    12. WT2.start();
    13. fileIDX++;
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 

    Basically that is it. Each WT opens it's corresponding file, makes changes to it and saves.

    --Sam

  5. #5
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread - parallel

    Unless you have left out critical code, you do not seem to be ensuring thread safety. You need a QWaitCondition and a QMutex. Check out the mandelbrot example.
    Here is the relevant code for a safe construction of a worker thread.
    Qt Code:
    1. class JobThread : public QThread
    2. {
    3. public:
    4. JobThread(QObject *parent)
    5. : QThread(parent)
    6. {
    7. abort = false;
    8. start(LowPriority);
    9. }
    10.  
    11. ~JobThread()
    12. {
    13. mutex.lock();
    14. abort = true;
    15. condition.wakeOne();
    16. mutex.unlock();
    17. wait();
    18. }
    19.  
    20. void addJob(Job job)
    21. {
    22. QMutexLocker locker(&mutex);
    23. this->jobs << job;
    24. condition.wakeOne();
    25. }
    26.  
    27. void run()
    28. {
    29. QMutexLocker lock(&mutex);
    30. while(!abort) {
    31. if (!jobs.isEmpty())
    32. {
    33. condition.wait(&mutex);
    34. continue;
    35. }
    36. Job job = jobs.takeFirst();
    37. lock.unlock();
    38.  
    39. while (!abort) {
    40. // do heavy computing
    41. process(job);
    42. emit progress(...);
    43. }
    44. lock.relock();
    45. }
    46. }
    47. private:
    48. mutable bool abort;
    49. QMutex mutex;
    50. QWaitCondition condition;
    51. QList<Job> jobs;
    52. };
    To copy to clipboard, switch view to plain text mode 
    I would also consider using QtConcurrent.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QThread - parallel

    It would be easier if you did it with a wait condition or using QtConcurrent. The code you posted is... well... error prone. For instance QThread::start() doesn't start a thread, as you would expect. It returns immediately and the thread will be started some time afterwards, so isRunning() might return false before the thread actually gets started.

    What you want can basically be obtained via:
    Qt Code:
    1. void doSomething(const QString &fileName){
    2. doSomethingWithTheFile(fileName);
    3. }
    4. //...
    5. QStringList fileNames = buildFileList();
    6. QtConcurrent::map(fileNames, doSomething);
    To copy to clipboard, switch view to plain text mode 

    No mess and will use all the available cores in your machine.

  7. #7
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread - parallel

    By using QtConcurrent, will I be able to update the GUI? I could not find anything in the docs about the relationship between QtConcurrent and the Main Thread (GUI).

    Thanks for all the help wysota!

  8. #8
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread - parallel


  9. #9
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread - parallel

    OK,

    This could be because I am a noob, but...

    Qt Code:
    1. class packageWindow : public QMainWindow
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. void processFile(const QString &myFile);
    7. };
    8.  
    9. QStringList myList;
    10. for( int i = 0; i < numFiles; i++ )
    11. {
    12. myList.append(allFiles[i]->text());
    13. }
    14. QtConcurrent::map(myList,processFile);
    To copy to clipboard, switch view to plain text mode 

    The QtConcurrent call generates an error:

    Qt Code:
    1. argument of type `void(packageWindow::)(const QString&)` does not match `void(packageWindow::*)(const QString&)`
    To copy to clipboard, switch view to plain text mode 

    What does THAT mean?
    Last edited by sgrant327; 12th April 2010 at 21:05.

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QThread - parallel

    You can't use a non-static member function from another class. It either has to be static or can't be a member function. What is allowed and what is not is described in Qt Concurrent docs.

  11. #11
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread - parallel

    Got it...

    Took me a while to get that EVERYTHING the QtConcurrent thread uses has to be static.

    Just having a bit of trouble with QFutureWatcher and QtConcurrent. Sometime the app crashes after about 20 files, other times it runs fine, but 'locks' the computer as all 8 cores are running at 100&#37;...

  12. #12
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QThread - parallel

    You can use
    Qt Code:
    1. QThreadPool::globalInstance->setMaxThreadCount()
    To copy to clipboard, switch view to plain text mode 
    to limit the number of threads.
    And if your application still is crashing, you are probably still accessing a shared variable in an unsafe way. I'm thinking of myList and allFiles.
    It sounds like QtConcurrent::mappedReduced could be a candidate for you.

  13. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QThread - parallel

    What exactly does your thread method do? Is there a chance you could post the code here?

  14. #14
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - parallel

    Quote Originally Posted by sgrant327 View Post
    Got it...

    Took me a while to get that EVERYTHING the QtConcurrent thread uses has to be static.

    Just having a bit of trouble with QFutureWatcher and QtConcurrent. Sometime the app crashes after about 20 files, other times it runs fine, but 'locks' the computer as all 8 cores are running at 100%...
    Because as is writen in documentation Programs written with QtConcurrent automatically adjust the number of threads used according to the number of processor cores available. So they consume 100% available cores.
    Your first idea with ThreadManager and WorkerThread is good. You must only create slot in ThreadManager and connect to them signal QThread::finished(). In this slot start worker with next file.

Similar Threads

  1. Progress Bar set value inside OpenMP parallel for
    By lixo1 in forum Qt Programming
    Replies: 2
    Last Post: 18th February 2010, 19:51
  2. Replies: 1
    Last Post: 6th February 2010, 09:54
  3. Combining sequential and parallel animation
    By mirelon in forum Qt Programming
    Replies: 0
    Last Post: 22nd January 2010, 15:28
  4. Parallel Interface
    By r00tz in forum Qt Programming
    Replies: 31
    Last Post: 19th November 2007, 12:50
  5. Parallel and serial I/O
    By Roberto in forum Qt Programming
    Replies: 3
    Last Post: 10th October 2007, 11:53

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.