Results 1 to 19 of 19

Thread: QMutex seems not to lock()

  1. #1
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question QMutex seems not to lock()

    Hello.. I am in the progress of parallelise a multi-agent model where "agents" are different instances (thousands) of a class and they have to independently perform a relatively cpu-intensive task (few seconds).
    Looks the perfect situation for a reentrant code .... it seems...
    My problem is that, even if I mutex.lock() all the should-be-concurrent code (for debugging reasons of course) my application crash, while if I use a single thread it works.
    This is the code that I implemented so far:
    Qt Code:
    1. void
    2. Manager_farmers::landAllocation(){
    3. // .. serial code ..
    4.  
    5. for (int i=0; i < nThreads; i++){
    6. Manager_farmers_threads* wThread = new Manager_farmers_threads;
    7. wThreads.push_back(wThread);
    8. }
    9.  
    10. // parallelise the code to z workingThreads..
    11. for (uint y=0;y<myAgents.size();y++){
    12. bool assigned = false;
    13. while(!assigned) {
    14. for (uint z=0;z<wThreads.size();z++){
    15. if (!wThreads[z]->isRunning()){
    16. wThreads[z]->assignJob(myAgents[y], freePlot);
    17. wThreads[z]->start();
    18. assigned = true;
    19. break;
    20. }
    21. }
    22. }
    23. }
    24.  
    25. // be sure that all threads are ended..
    26. for (int z=0; z < nThreads; z++){
    27. wThreads[z]->wait();
    28. }
    29.  
    30. // ..continue with serial code...
    31.  
    32. for (int i=0; i < nThreads; i++){
    33. delete wThreads[i]; // deleting the threads
    34. }
    35. }
    36.  
    37. void
    38. Manager_farmers_threads::assignJob(Agent_space* agent_h, const Pixel* plot_h){
    39. // .. this code shuld be run serialised by the main thread..
    40. agent = agent_h;
    41. plot = plot_h;
    42. agent->cachedOffer = 0;
    43. }
    44.  
    45. void
    46. Manager_farmers_threads::run(){
    47. // This code should be run parallelised...
    48. QMutex localMutex;
    49. localMutex.lock();
    50. agent->cachedOffer = agent->offerRentalPrice(plot);
    51. localMutex.unlock();
    52. }
    To copy to clipboard, switch view to plain text mode 
    The question is.. why for hell it is crashing even if all the code is locked ?

  2. #2
    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: QMutex seems not to lock()

    You are creating a local mutex so each entry to the method creates a private instance of the mutex so each thread works on its own instance of the mutex so there is never a situation when two threads try to lock the same mutex. You have to work on a single mutex for all threads.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMutex seems not to lock()

    Hi.. thanks for the answer.
    In fact I originally tried to use the QMutex as a member of the thread class, like it is done in the book "C++ GUI programming with Qt4" ("Syncronizing threads").

    The thread class looks now like this:
    Qt Code:
    1. class Manager_farmers_threads : public QThread {
    2. Q_OBJECT
    3.  
    4. public:
    5. Manager_farmers_threads();
    6. void assignJob(Agent_space* agent_h, const Pixel*plot_h);
    7.  
    8. protected:
    9. void run();
    10.  
    11. private:
    12. volatile Agent_space* agent;
    13. const Pixel* plot;
    14. QMutex mutex;
    15. };
    To copy to clipboard, switch view to plain text mode 
    However it still doesn't work (and it should't, as each thread would still have it's own mutex istance).

    If I understood correctly, you suggest to create the Mutex somewhere in the main thread and then giving pointers to the threads? Or create a function in the main thread to lock/unlock the mutex and call it from the threads?

  4. #4
    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: QMutex seems not to lock()

    This changes nothing. The mutex has to be static or global - different instances of the thread have to access the same instance of the mutex. The fact that the variable name of two mutexes is the same doesn't mean they are the same mutex.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Unhappy Re: QMutex seems not to lock()

    I created the Mutex in the main thread and gived threads a shared pointer, but still crashing (when I set nThreads=1 it's all going fine)

    Now the code looks like that:
    Qt Code:
    1. void
    2. Manager_farmers::landAllocation(){
    3. // .. serial code ..
    4.  
    5. QMutex* mutex = new QMutex;
    6. for (int i=0; i < nThreads; i++){
    7. Manager_farmers_threads* wThread = new Manager_farmers_threads;
    8. wThreads.push_back(wThread);
    9. }
    10.  
    11. // parallelise the code to z workingThreads..
    12. for (uint y=0;y<myAgents.size();y++){
    13. bool assigned = false;
    14. while(!assigned) {
    15. for (uint z=0;z<wThreads.size();z++){
    16. if (!wThreads[z]->isRunning()){
    17. wThreads[z]->assignJob(myAgents[y], freePlot, mutex);
    18. wThreads[z]->start();
    19. assigned = true;
    20. break;
    21. }
    22. }
    23. }
    24. }
    25.  
    26. // be sure that all threads are ended..
    27. for (int z=0; z < nThreads; z++){
    28. wThreads[z]->wait();
    29. }
    30.  
    31. // ..continue with serial code...
    32.  
    33. for (int i=0; i < nThreads; i++){
    34. delete wThreads[i]; // deleting the threads
    35. }
    36. delete mutex;
    37. }
    38.  
    39. void
    40. Manager_farmers_threads::assignJob(Agent_space* agent_h, const Pixel* plot_h, QMutex* mutex_h){
    41. // .. this code shuld be run serialised by the main thread..
    42. agent = agent_h;
    43. plot = plot_h;
    44. mutex = mutex_h;
    45. agent->cachedOffer = 0;
    46. }
    47.  
    48. void
    49. Manager_farmers_threads::run(){
    50. // This code should be run parallelised...
    51. mutex.lock();
    52. agent->cachedOffer = agent->offerRentalPrice(plot);
    53. mutex.unlock();
    54. }
    55.  
    56.  
    57. class Manager_farmers_threads : public QThread {
    58. Q_OBJECT
    59.  
    60. public:
    61. Manager_farmers_threads();
    62. void assignJob(Agent_space* agent_h, const Pixel*plot_h, QMutex* mutex_h);
    63.  
    64. protected:
    65. void run();
    66.  
    67. private:
    68. volatile Agent_space* agent;
    69. const Pixel* plot;
    70. QMutex* mutex;
    71. };
    To copy to clipboard, switch view to plain text mode 

  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: QMutex seems not to lock()

    What is the Pixel class?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMutex seems not to lock()

    Thank you for your answers.
    "Pixel" it's a non-gui class that describes the space in my model.
    Basically the parallelised code needs just read-only data on information stored on "pixels" and the idea is to eventually protect with mutex this kind of parts only, but the program crash even if I lock/unlock ALL the parallelised code (this is the funy side, becasue according on how I understood mutex looking there should not be any parallelised code when you lock it all ) .
    Rendering of the maps on screen is done much later on in the serial part of the model.

    Any how, this is the documentation for the Pixel class:
    http://www.regmas.org/doc/referenceM...lassPixel.html

  8. #8
    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: QMutex seems not to lock()

    Where exactly does the application crash? What does the debugger say?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. The following user says thank you to wysota for this useful post:

    sylvaticus (3rd July 2009)

  10. #9
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMutex seems not to lock()

    Sorry for the late response (I moved to an area without internet :-( ).

    The application crash when I use a call to a mathematical programming library named "glpk".

    "Program received signal SIGABRT (Aborted)"

    // solving the problem with the integer variables
    stat=lpx_integer(lpglpk);

    The re-entrant capability of this library is not assured, but the point is that it is wholly called from agent->cachedOffer = agent->offerRentalPrice(plot); that is protected by a mutex.
    By the way all the steps of solving the mathematical problem (initialise the problem, solving, getting the solution and deleting the problem) are done within the "offerRentalPrice()" function.
    So my question is: why even if I place a mutex this function is executed concurrently?

  11. #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: QMutex seems not to lock()

    Please introduce debug statements around locking and unlocking the mutex so that you can check the sequence of the calls. You can use QThread::currentThreadId() to provide information which thread is performing the lock/unlock operation.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #11
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Lightbulb Re: QMutex seems not to lock()

    I put debugging messages around the two lock/unlocks:
    Qt Code:
    1. void
    2. Manager_farmers_threads::run(){
    3. int threadId = currentThreadId();
    4. cout <<"A "<<threadId<<endl;
    5. mutex->lock();
    6. cout <<"B "<<threadId<<endl;
    7.  
    8. ( (Agent_farmer*) agent)->cachedOffer = ( (Agent_farmer*) agent)->offerRentalPrice(plot);
    9.  
    10. cout <<"C "<<threadId<<endl;
    11. mutex->unlock();
    12. cout <<"D "<<threadId<<endl;
    13. }
    To copy to clipboard, switch view to plain text mode 

    I'm attaching the output log...

    This is an other log with only ABCD:
    ************************************************** *****************
    *** !! Welcome to RegMAS - Regional Multi Agent Simulator !! ***
    *** For info & doc: http://www.regmas.org/doc ***
    *** Compiled on: Jul 3 2009 - 14:10:18 ***
    ************************************************** *****************

    Selected scenario: default
    **WARNING: No elements in the XML file. Expected at least one of type reclassRule
    **WARNING: No elements in the XML file. Expected at least one of type reclassRule
    ABCDABCDABCDABCDABCDABCDABACDBCDABCDABACDBCDABCDAB ACDBCDABCDABACDBCDAB
    The external library crash only if I use nThreads > 1.
    Furthermore, the second log were generated using the original, non-safe library, while the first log - crashing much later during the execution - were generated using a dev version of that library that is going in the direction of thread-safe.

    So my question is: if I have a thread-unsafe library and I try to access it from different threads, even if I access it in a serialised way (using mutexes), it could be any how dangerous.
    Is this sentence correct?
    Attached Files Attached Files

  13. #12
    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: QMutex seems not to lock()

    It seems that locking works fine. If the library uses some internal static data, the data might become corrupted if it is overwritten with another cycle of a function that operates on the data before the data is actually used somewhere. But it is impossible to determine that without knowing the structure of the library. You might try debugging the library itself.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. #13
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMutex seems not to lock()

    I managed to create a test case where I don't use any mutex, just a SINGLE separate thread that call the external library (glpk) solving an example problem.
    I use this thread in a loop that assigns new jobs to it when it is not busy.
    Glpk crashes when comparing the elapsed time using CPU clocks.

    The glpk maintainer told me that he doesn't think it is a glpk bug, so I am last with a problem either in my code (very likely) or in the QT thread library.
    You can find attached a small test case, but the core of the issue is in the above code:

    Qt Code:
    1. #include <glpk.h>
    2. #include <Thread.h>
    3.  
    4. using namespace std;
    5.  
    6. int main(int argc, char *argv[]){
    7.  
    8. cout << "Test on glpk using Qt Threads" << endl<<endl;
    9.  
    10. Thread wThread; // a simple subclass of QThread
    11. for (uint y=0;y<500;y++){
    12. bool assigned = false;
    13. while(!assigned) {
    14. if (!wThread.isRunning()){
    15. wThread.start(); // job done from the other thread. Just solve a simple linear programming problem (glpk documentation example)
    16. assigned = true;
    17. break;
    18. }
    19. }
    20. }
    21.  
    22. cout <<"All done without errors (crashing)"<<endl;
    23.  
    24. return 0;
    25. }
    To copy to clipboard, switch view to plain text mode 

    Am I doing something very naif???
    Attached Files Attached Files

  15. #14
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMutex seems not to lock()

    I managed to retrieve the error also doing a more simple loop:

    Qt Code:
    1. int main(int argc, char *argv[]){
    2.  
    3. cout << "Test on a glpk application using Qt Threads" << endl<<endl;
    4. Thread wThread;
    5. for (uint y=0;y<5000;y++){
    6. wThread.start(); // job done from the other thread
    7. wThread.wait();
    8. }
    9. cout <<"All done without errors (crashing)"<<endl;
    10. return 0;
    11. }
    To copy to clipboard, switch view to plain text mode 

    The error I have from glpk is:
    Assertion failed: xlcmp(env->t_last, t) <= 0
    Error detected in file glplib10.c at line 109
    I really do not understand why this external library crash if I put it on an external thread that I run consecutivly while it works whitout problems if I run it in the main thread.

  16. #15
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Exclamation Re: QMutex seems not to lock()

    It seems a Qt bug (but of course, I'm not sure..)
    http://bugreports.qt.nokia.com/browse/QTBUG-684

  17. #16
    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: QMutex seems not to lock()

    I don't think the bug report has anything to do with your code. The fact that you do use wait() and you do use threads doesn't mean the situation is the same as the one you described. It all depends what your thread does. Anyway you can make a workaround that the main thread waits on a dedicated wait condition. Another thing is whether it makes any sense to do something in another thread if you just block the main thread until it is finished. A producer-consumer pattern looks totally different than your code, above all it doesn't have any while loops.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. #17
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMutex seems not to lock()

    hello, in fact this code is also not working:
    Qt Code:
    1. Thread wThread; // a simple subclass of QThread
    2. for (uint y=0;y<500;y++){
    3. bool assigned = false;
    4. while(!assigned) {
    5. if (!wThread.isRunning()){
    6. wThread.start(); // job done from the other thread. Just solve a simple linear programming problem (glpk documentation example)
    7. assigned = true;
    8. break;
    9. }
    10. }
    11. }
    To copy to clipboard, switch view to plain text mode 
    The idea is to have a vector of threads doing the jobs simultaneously and for doing this I will need a patched version of the glpk library, but I stopped when I noticed that even when I use a single thread I have problems.
    Then I tried to put the example on its minimum terms.

    The Thread::run() function just does something like:
    Qt Code:
    1. for (uint i=0;i<3;i++){
    2. glp_prob *lp;
    3. lp = glp_create_prob();
    4. [...]
    5. glp_load_matrix(lp, 9, ia, ja, ar);
    6. glp_simplex(lp, NULL);
    7. [...]
    8. glp_delete_prob(lp);
    9. }
    To copy to clipboard, switch view to plain text mode 

    This code works if I call it directly in the main thread (that really in the real application is itself a working thread separated from the GUI), but crash when called from wThread. I thought that even if the bug report refers to the "wait()" function, the cause underlying it would be the same causing the problem in my situation.

  19. #18
    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: QMutex seems not to lock()

    From what I see you are trying to start 500 threads using the same thread controller object. This is simply bound to fail.

    Try this:
    Qt Code:
    1. class MyRunnable : public QRunnable {
    2. void run(){
    3. for (uint i=0;i<3;i++){
    4. glp_prob *lp;
    5. lp = glp_create_prob();
    6. [...]
    7. glp_load_matrix(lp, 9, ia, ja, ar);
    8. glp_simplex(lp, NULL);
    9. [...]
    10. glp_delete_prob(lp);
    11. }
    12. }
    13. };
    14. //...
    15. for(int i = 0; i<500; i++){
    16. QThreadPool::globalInstance()->start(new MyRunnable);
    17. }
    To copy to clipboard, switch view to plain text mode 

    You can call this before you enter the loop to make sure only one thread at once is ran:
    Qt Code:
    1. QThreadPool::globalInstance()->setMaxThreadCount(1);
    To copy to clipboard, switch view to plain text mode 
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  20. The following user says thank you to wysota for this useful post:

    sylvaticus (4th December 2009)

  21. #19
    Join Date
    Dec 2007
    Location
    Ancona, Italy
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Wink Re: QMutex seems not to lock()

    Quote Originally Posted by wysota View Post
    From what I see you are trying to start 500 threads using the same thread controller object. This is simply bound to fail.

    Try this:[...]
    Thank you.. this method is working. However, I tried debugging my first code (those with the isRunning() check) with QThread::currentThread() and I noticed it was producing only two threads (one main and one working) as expected, not 500, so I still don't know why it wasn't working...

Similar Threads

  1. Lock a file
    By euthymos in forum Qt Programming
    Replies: 22
    Last Post: 27th December 2010, 23:29
  2. New to QMutex
    By durbrak in forum Qt Programming
    Replies: 3
    Last Post: 12th March 2009, 21:16
  3. QMutex is not working in release mode
    By bitChanger in forum Qt Programming
    Replies: 3
    Last Post: 25th April 2007, 13:32
  4. appbar: allocate screen space (dock and lock)
    By mito in forum Qt Programming
    Replies: 1
    Last Post: 20th April 2007, 18:39
  5. Replies: 3
    Last Post: 12th October 2006, 21:48

Tags for this Thread

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.