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. Slot called multiple times to a blocking function in the same thread
QtWS25 Last Chance

Slot called multiple times to a blocking function in the same thread

Scheduled Pinned Locked Moved Solved General and Desktop
guisignals&slotsthreading
13 Posts 4 Posters 6.3k Views
  • 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.
  • M Offline
    M Offline
    moffa13
    wrote on 6 Jun 2017, 23:57 last edited by moffa13 6 Jun 2017, 23:58
    #1

    Hello,

    I was wondering what would happen if a widget in my gui was calling the same slot multiple times, so everything is happening in the same thread.

    The slot is a blocking function which takes lot of time to end.

    I saw that it was able to handle the signals emitting to the same slot (for example clicking a button) if there was a QApplication::processEvents(); somewhere in the slot

    Would'nt it cause memory problems if the function is called again but the first call isn't finished yet ?

    Thanks for help !

    J J 2 Replies Last reply 7 Jun 2017, 03:32
    0
    • M moffa13
      6 Jun 2017, 23:57

      Hello,

      I was wondering what would happen if a widget in my gui was calling the same slot multiple times, so everything is happening in the same thread.

      The slot is a blocking function which takes lot of time to end.

      I saw that it was able to handle the signals emitting to the same slot (for example clicking a button) if there was a QApplication::processEvents(); somewhere in the slot

      Would'nt it cause memory problems if the function is called again but the first call isn't finished yet ?

      Thanks for help !

      J Offline
      J Offline
      joeQ
      wrote on 7 Jun 2017, 03:32 last edited by
      #2

      @moffa13 Hi, friend welcome.

      About what you said, the same slot multiple times, maybe you wrote some code to emit the signal(value changed signal, state changed signal ...).
      some time, we called the qt inner function, these function maybe changed some value and emit some signal. like QListWidget::currentRowChanged(int currentRow) signal

      1. user can clicked item to emit this signal;
      2. i also can setCurrentRow(row) in my program to emit this signal.

      i called this slot signal loop; like below code snippet;

      connect(listWidget,&QListWidget::currentRowChanged,this,&Class::RowChanged);
      
      void Class::RowChanged(int row)
      {
          /** it is best to disconnect begin of slot fuction */
          disconnect(listWidget,&QListWidget::currentRowChanged,this,&Class::RowChanged);
      
          /** maybe at here i use setCurrent() function to changed the current row ,and will emit row changed signal again */
      
          connect(listWidget,&QListWidget::currentRowChanged,this,&Class::RowChanged);
      }
      

      If I guessed wrong. Can you show some code snippet for here? it will help us to understand your problem well.

      Just do it!

      1 Reply Last reply
      0
      • M moffa13
        6 Jun 2017, 23:57

        Hello,

        I was wondering what would happen if a widget in my gui was calling the same slot multiple times, so everything is happening in the same thread.

        The slot is a blocking function which takes lot of time to end.

        I saw that it was able to handle the signals emitting to the same slot (for example clicking a button) if there was a QApplication::processEvents(); somewhere in the slot

        Would'nt it cause memory problems if the function is called again but the first call isn't finished yet ?

        Thanks for help !

        J Offline
        J Offline
        jsulm
        Lifetime Qt Champion
        wrote on 7 Jun 2017, 04:20 last edited by
        #3

        @moffa13 said in Slot called multiple times to a blocking function in the same thread:

        Would'nt it cause memory problems if the function is called again but the first call isn't finished yet ?

        Memory problems? Usually not. But you could have other issues if the slot you're calling isn't re-entrant. For example if you have a static variable inside the slot.
        But in general you should avoid blocking slots and QApplication::processEvents() is nothing more than an ugly work around and a sign of bad design. Move long lasting operations to other threads.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        4
        • M Offline
          M Offline
          moffa13
          wrote on 7 Jun 2017, 11:47 last edited by
          #4

          @joeQ The slot being called multiple time is not accidental ; it just happens for example if I push a button 2 times.

          The code is here : Github

          addWhateverToList is the slot being called and FilesEncrypt::getFilesFromDirRecursive is the function that takes time.

          @jsulm I used QApplication::processEvents() just to test what happens if my function becames "non-blocking".

          1 Reply Last reply
          0
          • V Offline
            V Offline
            VRonin
            wrote on 7 Jun 2017, 12:28 last edited by VRonin 6 Jul 2017, 12:33
            #5

            The correct way to proceed, as mentioned by @jsulm is to move the heavy lifting to a separate thread but,

            This is a hack!

            You can put a queue slot in between:

            private:
            Q_SLOT void lenghtyOp(){
            lenghtyOpQueued =false;
            // do the slow stuff
            }
            bool lenghtyOpQueued = false;
            public:
            Q_SLOT void queueLenghty(){
            if(lenghtyOpQueued) return;
            lenghtyOpQueued =true;
            QTimer::singleShot(100,this,SLOT(lenghtyOp()));
            }
            

            now connect your button to queueLenghty rather than to lenghtyOp

            also, you probably want to add an argument to processEvents: QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            1
            • M Offline
              M Offline
              moffa13
              wrote on 7 Jun 2017, 16:50 last edited by
              #6

              @VRonin said in Slot called multiple times to a blocking function in the same thread:

              You can put a queue slot in between:

              private:
              Q_SLOT void lenghtyOp(){
              lenghtyOpQueued =false;
              // do the slow stuff
              }
              bool lenghtyOpQueued = false;
              public:
              Q_SLOT void queueLenghty(){
              if(lenghtyOpQueued) return;
              lenghtyOpQueued =true;
              QTimer::singleShot(100,this,SLOT(lenghtyOp()));
              }
              

              I prefered to use QtConcurrent::run it's much cleaner but thanks for the trick !

              Thank you all for your answers :)

              V 1 Reply Last reply 7 Jun 2017, 17:08
              0
              • M moffa13
                7 Jun 2017, 16:50

                @VRonin said in Slot called multiple times to a blocking function in the same thread:

                You can put a queue slot in between:

                private:
                Q_SLOT void lenghtyOp(){
                lenghtyOpQueued =false;
                // do the slow stuff
                }
                bool lenghtyOpQueued = false;
                public:
                Q_SLOT void queueLenghty(){
                if(lenghtyOpQueued) return;
                lenghtyOpQueued =true;
                QTimer::singleShot(100,this,SLOT(lenghtyOp()));
                }
                

                I prefered to use QtConcurrent::run it's much cleaner but thanks for the trick !

                Thank you all for your answers :)

                V Offline
                V Offline
                VRonin
                wrote on 7 Jun 2017, 17:08 last edited by
                #7

                @moffa13 said in Slot called multiple times to a blocking function in the same thread:

                QtConcurrent::run it's much cleaner

                I don't want to be that guy, but I'd bet my left eye you are doing multi-threading wrong here. Are you sure you don't have a race-condition on ui->tableWidget if you use that?

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  moffa13
                  wrote on 7 Jun 2017, 17:18 last edited by
                  #8

                  @VRonin said in Slot called multiple times to a blocking function in the same thread:

                  @moffa13 said in Slot called multiple times to a blocking function in the same thread:

                  QtConcurrent::run it's much cleaner

                  I don't want to be that guy, but I'd bet my left eye you are doing multi-threading wrong here. Are you sure you don't have a race-condition on ui->tableWidget if you use that?

                  I don't understand why would I have this ?
                  Here's my final code : link

                  My lambda function is not doing anything to ui->tableWidget

                  1 Reply Last reply
                  0
                  • V Offline
                    V Offline
                    VRonin
                    wrote on 7 Jun 2017, 17:37 last edited by VRonin 6 Jul 2017, 17:37
                    #9

                    I have to be honest, I did not dig deep in to your code, but at first glance it looks like I lost my left eye in the bet 😉

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      moffa13
                      wrote on 7 Jun 2017, 18:56 last edited by
                      #10

                      Well, I think there is no problem here because the only thing my thread is changing is a QTableWidgetItem which cannot be changed by something else by the logic of my code.

                      V 1 Reply Last reply 8 Jun 2017, 16:28
                      0
                      • M moffa13
                        7 Jun 2017, 18:56

                        Well, I think there is no problem here because the only thing my thread is changing is a QTableWidgetItem which cannot be changed by something else by the logic of my code.

                        V Offline
                        V Offline
                        VRonin
                        wrote on 8 Jun 2017, 16:28 last edited by
                        #11

                        @moffa13 said in Slot called multiple times to a blocking function in the same thread:

                        my thread is changing is a QTableWidgetItem which cannot be changed by something else

                        if the QTableWidgetItem is visible in a view then the view will directly call the item for read every repaint, hence race condition

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        3
                        • M Offline
                          M Offline
                          moffa13
                          wrote on 8 Jun 2017, 19:34 last edited by moffa13 6 Aug 2017, 19:34
                          #12

                          @VRonin said in Slot called multiple times to a blocking function in the same thread:

                          @moffa13 said in Slot called multiple times to a blocking function in the same thread:

                          my thread is changing is a QTableWidgetItem which cannot be changed by something else

                          if the QTableWidgetItem is visible in a view then the view will directly call the item for read every repaint, hence race condition

                          Actually I said something wrong. The part who is modifying the QTableWidgetItem is the QFutureWatcher<>::finished slot, which is accessed by the main thread, I think.
                          One question : Is it bad to lock and unlock a mutex multiple times ?

                          For example :

                          _mutex.lock();
                          //Some var to be protected
                          _mutex.unlock();
                          //Thread-safe heavy function
                          _mutex.lock();
                          //Some var to be protected
                          _mutex.unlock();
                          

                          Thanks !

                          V 1 Reply Last reply 9 Jun 2017, 06:47
                          0
                          • M moffa13
                            8 Jun 2017, 19:34

                            @VRonin said in Slot called multiple times to a blocking function in the same thread:

                            @moffa13 said in Slot called multiple times to a blocking function in the same thread:

                            my thread is changing is a QTableWidgetItem which cannot be changed by something else

                            if the QTableWidgetItem is visible in a view then the view will directly call the item for read every repaint, hence race condition

                            Actually I said something wrong. The part who is modifying the QTableWidgetItem is the QFutureWatcher<>::finished slot, which is accessed by the main thread, I think.
                            One question : Is it bad to lock and unlock a mutex multiple times ?

                            For example :

                            _mutex.lock();
                            //Some var to be protected
                            _mutex.unlock();
                            //Thread-safe heavy function
                            _mutex.lock();
                            //Some var to be protected
                            _mutex.unlock();
                            

                            Thanks !

                            V Offline
                            V Offline
                            VRonin
                            wrote on 9 Jun 2017, 06:47 last edited by
                            #13

                            @moffa13 said in Slot called multiple times to a blocking function in the same thread:

                            One question : Is it bad to lock and unlock a mutex multiple times ?

                            No, that's exactly what they are deigned for

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            1 Reply Last reply
                            0

                            2/13

                            7 Jun 2017, 03:32

                            topic:navigator.unread, 11
                            • Login

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