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] How to wait in a proper way for multiple signals?
QtWS25 Last Chance

[SOLVED] How to wait in a proper way for multiple signals?

Scheduled Pinned Locked Moved General and Desktop
8 Posts 2 Posters 5.2k 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.
  • R Offline
    R Offline
    RolBri
    wrote on last edited by RolBri
    #1

    Hi,

    I would like to wait for multiple signals.
    One class loads data to be processed. Then the data is processed in several class instances in different threads.
    After all threads are finished I would like to load new data for processing.

    In the data loading class I have a corresponding function to set bool variables whether a thread is active or not.
    The threadStarted signal is used to set the bool variables to active and the threadFinished signal is used to set them to non active.

    I just use a while loop where I am waiting that all bool variables are zero for inactive.

    In the console I checked the order of starting and stopping and all variables are set in a proper order.
    Sadly the program does not leave the while loop sometimes and just hangs.

    Do you have an idea what could be wrong or how to wait in a better way?

    EDIT: I just noticed it just happens if the while loop is empty.
    If I wait for 1 ms after every check, it does not hang anymore, but why is that?

    Thank you very much :-)

    1 Reply Last reply
    1
    • C Offline
      C Offline
      code_fodder
      wrote on last edited by
      #2

      Can you post your while loop code?

      When you introduce a 1ms wait, you are also providing a cancellation/switching point. Meaning that your process can have a chance to go off and do other things. Without that wait your loop is probably taking 100% of processing time.

      A better way to do this is without a loop per say. You can run in a more state-machine/event driven way, such that when you receive a "Thread complete" signal, you check the state of all the threads. If they are not all finished then do nothing. If they are all finished, then do your "finish action" (this could be to emit a signal or anything). Would be easier to describe better what to do if we can see your loop code : )

      1 Reply Last reply
      0
      • R Offline
        R Offline
        RolBri
        wrote on last edited by RolBri
        #3

        Ok, thank you very much :-)
        This is my code:
        .cpp:

        while(processingThread1active==true || processingThread2active==true || processingThread3active==true || processingThread4active==true || processingThread5active==true || processingThread6active==true ) 
                {
                    waitKey(1); //there must be something done in the while loop otherwise it hangs!
                }
        

        .h:

        private slots:
        
             void thread1Started() {processingThread1active=true; std::cout << "1start" << std::endl;}
             void thread2Started() {processingThread2active=true; std::cout << "2start" << std::endl;}
             void thread3Started() {processingThread3active=true; std::cout << "3start" << std::endl;}
             void thread4Started() {processingThread4active=true; std::cout << "4start" << std::endl;}
             void thread5Started() {processingThread5active=true; std::cout << "5start" << std::endl;}
             void thread6Started() {processingThread6active=true; std::cout << "6start" << std::endl;}
        
             void thread1Finished() {processingThread1active=false; std::cout << "1stopp" << std::endl;}
             void thread2Finished() {processingThread2active=false; std::cout << "2stopp" << std::endl;}
             void thread3Finished() {processingThread3active=false; std::cout << "3stopp" << std::endl;}
             void thread4Finished() {processingThread4active=false; std::cout << "4stopp" << std::endl;}
             void thread5Finished() {processingThread5active=false; std::cout << "5stopp" << std::endl;}
             void thread6Finished() {processingThread6active=false; std::cout << "6stopp" << std::endl;}
        
        C 1 Reply Last reply
        0
        • R RolBri

          Ok, thank you very much :-)
          This is my code:
          .cpp:

          while(processingThread1active==true || processingThread2active==true || processingThread3active==true || processingThread4active==true || processingThread5active==true || processingThread6active==true ) 
                  {
                      waitKey(1); //there must be something done in the while loop otherwise it hangs!
                  }
          

          .h:

          private slots:
          
               void thread1Started() {processingThread1active=true; std::cout << "1start" << std::endl;}
               void thread2Started() {processingThread2active=true; std::cout << "2start" << std::endl;}
               void thread3Started() {processingThread3active=true; std::cout << "3start" << std::endl;}
               void thread4Started() {processingThread4active=true; std::cout << "4start" << std::endl;}
               void thread5Started() {processingThread5active=true; std::cout << "5start" << std::endl;}
               void thread6Started() {processingThread6active=true; std::cout << "6start" << std::endl;}
          
               void thread1Finished() {processingThread1active=false; std::cout << "1stopp" << std::endl;}
               void thread2Finished() {processingThread2active=false; std::cout << "2stopp" << std::endl;}
               void thread3Finished() {processingThread3active=false; std::cout << "3stopp" << std::endl;}
               void thread4Finished() {processingThread4active=false; std::cout << "4stopp" << std::endl;}
               void thread5Finished() {processingThread5active=false; std::cout << "5stopp" << std::endl;}
               void thread6Finished() {processingThread6active=false; std::cout << "6stopp" << std::endl;}
          
          C Offline
          C Offline
          code_fodder
          wrote on last edited by code_fodder
          #4

          @RolBri
          So, yeah, I think what I said before is the case.

          Remove your while loop, and in your slot call a function:

              void thread<x>Started() {handleThreadEvent(x, true)}
              void thread<x>Finished() {handleThreadEvent(x, false)}
          // <x> is the thread number
          

          Then your function:

              handleThreadEvent(int x, bool value)
              {
                  // Make your flags an array of bools (easier to process)
                  ProcessingThreadAactive[x] = value;
              
                  // Check if threads are finished
                  for (int i = 0; i < numThreads; i++)
                  {
                      bool finished = true;
                      if (ProcessingThreadAactive[i] == true)
                      {
                          finished = false;
                          // Do end actions here
                          break;
                      }
                  }
              }
          

          The advantage here is that you are only processing your check when your receive a thread event, also there is less repeated code) (not tested the code, so you may need to tweak it)

          1 Reply Last reply
          1
          • R Offline
            R Offline
            RolBri
            wrote on last edited by
            #5

            Thank you very much.
            The problem is that the class is dependent on different timers and variables I have not mentioned.

            I understood your code and I see that this is far better than a loop, but because of the class structure it is a lot of work and not so easy to change it to a state machine.

            If I can avoid the hanging I will stick to the loop solution.

            Next time if I write something similar I take your solution :-)

            1 Reply Last reply
            0
            • C Offline
              C Offline
              code_fodder
              wrote on last edited by
              #6

              Its true, if you can get your code to work for now then go with that, at least you understand what is happening and so it's your choice : )

              Another option for you to mull over is conditional variables/mutex. I have not used the Qt version of this before but it works in the same way. Take a look at this. It allows you to keep your "wait" inline, but instead of polling values in a loop (inefficient), it allows the thread to "sleep/block" until notified. This would be easier to implement into an existing code base to replace a loop without modifying the structure of your code.

              Requires a bit more work on your part, so if you can be bothered then its worth doing (even just to learn).

              1 Reply Last reply
              1
              • R Offline
                R Offline
                RolBri
                wrote on last edited by RolBri
                #7

                Could you please check your link?
                It is not working :-(
                I am really interested in the other solution as it looks like I cannot continue with my old way... ;-)

                C 1 Reply Last reply
                0
                • R RolBri

                  Could you please check your link?
                  It is not working :-(
                  I am really interested in the other solution as it looks like I cannot continue with my old way... ;-)

                  C Offline
                  C Offline
                  code_fodder
                  wrote on last edited by
                  #8

                  @RolBri Oh... not sure what happened, let me try again:

                  Here is the link in text: http://doc.qt.io/qt-4.8/qwaitcondition.html

                  Let me try the auto format again: here

                  1 Reply Last reply
                  1

                  • Login

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