Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED]Cann't get correct mutex status
Forum Updated to NodeBB v4.3 + New Features

[SOLVED]Cann't get correct mutex status

Scheduled Pinned Locked Moved General and Desktop
10 Posts 3 Posters 2.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DiIvPa
    wrote on last edited by
    #1

    Dear Forumers, I cann't synchronise threads (main and parallel one ) using mutex. When I emit signal from parallel thread to main and use mutex in main, the parallel thread are still working. I wrote a little example (see below). Where is my mistake ? It looks like I didn't understand something. Thank you all in advance for your time.
    main.cpp
    @
    #include <myWindow.h>
    int main(int argc, char **argv)
    {
    QApplication app(argc, argv);
    MainWindow *my_window = new MainWindow();

    my_window -> show();

    return app.exec();

    }
    @

    myWindow.h

    @
    #include <QMutex>

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    

    QMutex *mutex_MainWindow;
    MainWindow( QWidget *parent = 0);

    private slots:
    void DoMessageReceived();
    };

    #endif // MYWINDOW_H
    @

    myWindow.cpp

    @
    #include "myWindow.h"
    #include "mythread.h"
    #include <QtTest/QTest>//В .pro файле добавить надо QT += testlib

    MainWindow::MainWindow( QWidget *parent) :
    QMainWindow(parent),
    mutex_MainWindow(new QMutex)
    {
    MyThread *mThread= new MyThread(mutex_MainWindow);

    connect(
    mThread, SIGNAL( MessageReceived () ),
    this, SLOT ( DoMessageReceived () )
    );
    mThread -> start();
    }
    void MainWindow::DoMessageReceived(){
    if( mutex_MainWindow -> tryLock ()) {
    qDebug() << "MainWindow::DoMessageReceivedMessage: tryLocked == true"
    << "\n------------------------------------------------------------";
    mutex_MainWindow -> unlock();
    QMutexLocker locker (mutex_MainWindow);
    }
    else
    qDebug() << "myWidget::receivedCanMessage: tryLocked == false"
    << "\n------------------------------------------------------------";
    qDebug() << "-----------------------------------------mutex_MainWindow = "
    << mutex_MainWindow;
    qDebug()
    << "***** MainWindow::DoMessageReceived: mutex locked -> QTest::qSleep(300000000 ms) ";
    QTest::qSleep(300000000);
    qDebug()
    << "****** MainWindow::DoMessageReceived: continue after qSleep(300000000 ms) ";
    return;
    }
    @

    mythread.h

    @
    #ifndef MYTHREAD_H
    #define MYTHREAD_H

    #include <QApplication>
    #include <QtGui>
    #include <QtCore>
    #include <QMutex>
    #include <QMutexLocker>
    #include <QDebug>

    class MyThread : public QThread
    {
    Q_OBJECT

    private:
    

    QMutex *mutex_thread;

    public:

    explicit MyThread( QMutex * , QWidget *parent = 0 );
    bool running;
    int n_cycle;
    protected:
    void run();

    signals :
    void MessageReceived();
    };

    #endif // MYTHREAD_H
    @

    mythread.cpp

    @
    #include "mythread.h"

    MyThread::MyThread(QMutex* mu, QWidget *parent ) :
    QThread( parent ),
    mutex_thread(mu),
    running(true),
    n_cycle(0)
    {
    qDebug() << "Constructor : mutex ="
    << mutex_thread;
    }

    void MyThread::run(){

    while (running) {
    qDebug() << " thread running -------------------------mutex ="
    << mutex_thread;
    // QMutexLocker locker (mutex_ObjectGetting);
    if( mutex_thread -> tryLock ()) {
    qDebug()
    << "thread: tryLocked==true"

    << "\n------------------------------------------------------------";
    mutex_thread -> unlock ();
    }
    else
    qDebug()
    << "thread: tryLocked==false"
    << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
    mutex_thread -> lock ();
    // doing something ...
    mutex_thread -> unlock ();
    emit MessageReceived();
    qDebug()
    << "thread: emit MessageReceived(), mutex unlocked -> usleep(10000) ";
    usleep(10000);
    n_cycle++;
    if(n_cycle == 4) running = false;
    }
    }
    @

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      What are you trying to do exactly ? Currently you are just locking your mutex in their respective thread and your code doesn't look like it needs mutex at all

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • D Offline
        D Offline
        DBoosalis
        wrote on last edited by
        #3

        How about sharing some output. Also did you try set the Recursive attribute for the QMutex.

        Also in your thread you always do an unlock, even if not locked here. According to the QMutex documentation for unlock():

        bq. Unlocks the mutex. Attempting to unlock a mutex in a different thread to the one that locked it results in an error. Unlocking a mutex that is not locked results in undefined behavior.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          DiIvPa
          wrote on last edited by
          #4

          Hi, SGaist, I need to get a message in the parallel thread and send one to the main thread to treat one and want to stop the parallel thread till the main thread will finish the treatment of the current message. I can do it by the QQueue and so on but I decided that a mutex is appropriate way to do this. And I knew about the Recursive attribute for the QMutex but I thought that I dont't need one but maybe I was wrong ?
          For DBoosalis: this is an example to demonstrate the problem. It looks like the mutex doesn't work like I want. In real soft I got this problem and cann't overcome one myself. I am using tryLock() to see the mutex is locked or is not. If I didn't mistake I always locked and unlock mutex in the same thread. That's it.
          Thank you for your time. Any suggestion ?

          1 Reply Last reply
          0
          • D Offline
            D Offline
            DiIvPa
            wrote on last edited by
            #5

            Dear Forumers, I see that I did something wrong in my example. In the parallel thread I am using tryLock and forgot that it will continue even the mutex was locked. So I corrected it. Now it works like I intended to show the problem. The parallel thread has not to work after the emiting signal receivedMessage till the main thread will finish to process received message but it works. Thank you.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Then it should rather be a QWaitCondition or use a signal connected using the Qt::BlockingQueuedConnection type.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • D Offline
                D Offline
                DiIvPa
                wrote on last edited by
                #7

                Dear SGaist, indeed I have used Qt::BlockingQueuedConnection and it works properly. thank you very much. So the p[roblem solved also I doesn't understand why the mutex doesn't work the same way. Anyway the solution looks even better because your valuable advice. Here is the changed codes just in case for reference:

                myWindow.cpp

                @
                #include "myWindow.h"
                #include "mythread.h"
                #include <QtTest/QTest>//В .pro файле добавить надо QT += testlib

                MainWindow::MainWindow( QWidget *parent) :
                QMainWindow(parent),
                mutex_MainWindow(new QMutex)
                {
                MyThread *mThread= new MyThread(mutex_MainWindow);

                connect(
                mThread, SIGNAL( MessageReceived () ),
                this, SLOT ( DoMessageReceived () ),
                Qt::BlockingQueuedConnection);
                mThread -> start();
                }
                void MainWindow::DoMessageReceived(){
                qDebug()
                << "***** MainWindow::DoMessageReceived -> Qt::BlockingQueuedConnection\n"
                << "***** called QTest::qSleep(3000) ";
                QTest::qSleep(3000);
                qDebug()
                << "****** MainWindow::DoMessageReceived: continue after qSleep(3000 ms) ";
                return;
                }
                @

                mythread.cpp

                @
                #include "mythread.h"

                MyThread::MyThread(QMutex* mu, QWidget *parent ) :
                QThread( parent ),
                mutex_thread(mu),
                running(true),
                n_cycle(0)
                {
                qDebug() << "Constructor : mutex ="
                << mutex_thread;
                }

                void MyThread::run(){

                while (running) {
                n_cycle++;
                qDebug() << " thread running: emit MessageReceived n_cycle = " << n_cycle;

                emit MessageReceived();
                
                if(n_cycle == 4) running = false;
                

                }
                }
                @

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  A mutex is not meant to be used as a "waiting point". It's used to protect access to a resource that can be accessed from several threads.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    DiIvPa
                    wrote on last edited by
                    #9

                    That's what I have been intended to do. I get message in the parallel thread and send one to the main thread and flash the mutex to avoid the access to reading a new message. But it doesn't work in my case. In my soft I have several threads but I intended to protect resourses
                    (the structure where I put the read message) only from one of them as in my simple example. The Qt::BlockingQueuedConnection does the same thing for me but I thought that mutex has to do the same, isn't it ?

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Not necessarily no. You should also take a look QSemaphore, QWaitCondition and QReadWriteLock

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved