Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QMutex: destroying locked mutex and QWaitCondition: mutex destroy failure: Device or resource busy



  • I am a very beginner to Qt, working on Qthreads. I was using QtConcurrent::run to run my functions on threads and iam getting the below warnings but the code executes well and displays entire output.. so, do i need to consider these warnings or leave them

    QWaitCondition: mutex destroy failure: Device or resource busy
    QMutex: destroying locked mutex
    


  • @rahult said in QMutex: destroying locked mutex and QWaitCondition: mutex destroy failure: Device or resource busy:

    I am a very beginner to Qt, working on Qthreads. I was using QtConcurrent::run to run my functions on threads

    I read this so many times! If you are a "beginner", may I ask why you feel you need QThreads & QConcurrent to do whatever you are trying to achieve? It's not impossible that you do need it, but so often we find beginners do not, and threading/concurrent is about the hardest thing to get right....



  • @JonB I was working for a AI project where we are developing a face recognition system. For preparing a demo we are preparing a GUI with Qt, so we wanted different blocks of code to run in parallel and thought QThreads would be good choice.


  • Lifetime Qt Champion

    Hi
    You could install a message handler
    https://stackoverflow.com/questions/4954140/how-to-redirect-qdebug-qwarning-qcritical-etc-output

    and compare the msg string to "QMutex: destroying locked mutex" and have a breakpoint when it matches.

    Then when it stops at this breakpoint, you have the call stack and you can see what code that produce this
    message.
    While they might not harm the app as such its best to find out why they come.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    If I may, you should reconsider the design of your pipeline and take into account the asynchronous nature of Qt. In the end you are blocking at several points in your code.

    You likely want your parallel operations be done in sequential steps you should avoid the waitForFinished calls and just trigger the next step when the finished signal is called.

    You maybe interested in representing your pipeline like a state machine to have a good representation of the flow it should follow.



  • @mrjj thank you for the information.. when i followed those steps it shows line number and function name as null as below

    Warning: QWaitCondition: mutex destroy failure: Device or resource busy ((null):0, (null))
    Warning: QMutex: destroying locked mutex ((null):0, (null))
    


  • @rahult
    If you have followed @mrjj's suggestion, you have written your own message handler. You need to put a debugger breakpoint on, say, the line below case QtWarningMsg:. When that is hit the debugger will stop (before it prints the message). You then need to find the debugger's "stack trace" window. That will show you have stopped inside your myMessageOutput() method. Look up/down the stack trace for where in your code caused this warning to be issued. That is then the code you need to examine to see why you have a problem.



  • @JonB sorry if my question seems ignorant when i put a break point below case QtWarningMsg: ,
    for "Warning: QMutex: destroying locked mutex" message debugger stack trace is like this it shows
    Screenshot from 2020-09-08 16-02-49.png

    this means is there any issue with the declaration of QFuture variables


  • Moderators

    @rahult Is your mutex by chance a scoped variable instead of a class member ?



  • @J-Hilk do you mean my QFuture variables ? if it is they are globally declared


  • Moderators

    @rahult Let me rephrase that question.

    How do you receive/store the data when the run of QtConcurrent finishes ?

    Do you use QMutexs, do you rely on return of QFuture or do you emit signals?

    and can you show that part of the code?



  • @J-Hilk Thank you... I am using QFuture

    future2 = QtConcurrent::run(this,&MainWindow::function2,0);
    
    void MainWindow::function2(int buf_id)
    {
        if(pro_buf.size() > 0)
        {
            buf_id = std::move(free_buff.front());
            detect_images[buf_id].push_back(std::move(pro_buf.front()));
            pro_buf.pop();
            free_buff.pop();
            cnt++;
            string img_name = to_string(cnt);
            string add(".jpg");
            string name = img_name + add;
            MainWindow::process(name,buf_id);
            if(future3.isRunning())
            {
                future3.waitForFinished();
            }
            future3 = QtConcurrent::run(this,&MainWindow::function3,name,buf_id);
        }
        else if(terminate_th)
        {
    
            if(future3.isRunning())
            {
                future3.waitForFinished();
            }
            exit_condition = 1;
            return;
        }
        future_n = QtConcurrent::run(this,&MainWindow::function2,buf_id);
    }

Log in to reply