Results 1 to 19 of 19

Thread: QMutex seems not to lock()

Hybrid View

Previous Post Previous Post   Next Post Next Post
  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,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 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,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 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,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 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,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 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,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 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

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
  •  
Qt is a trademark of The Qt Company.