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. Infinite loop and signal deluge
Forum Updated to NodeBB v4.3 + New Features

Infinite loop and signal deluge

Scheduled Pinned Locked Moved General and Desktop
35 Posts 6 Posters 17.9k 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.
  • F Offline
    F Offline
    Franzk
    wrote on 26 May 2011, 14:40 last edited by
    #18

    It will slow down your thread somewhat, yes. If the thread cannot wait, you should probably go for Gerolf's solution or something like it.

    "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

    http://www.catb.org/~esr/faqs/smart-questions.html

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JulienMaille
      wrote on 26 May 2011, 14:44 last edited by
      #19

      [quote author="Franzk" date="1306420801"]Gerolf's solution or something like it.[/quote] Any details on this?
      Gerolf method could work with text (because it does not always change), but I also emit pointer to images. And after each loop the image changes, so I need to either:

      • wait for the event to be processed (in a performance friendly fashion)
      • trash events if too many of them are fired

      I cannot use this "emit only if required" idea, because I can not decide if it's required based on the content of the image.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Franzk
        wrote on 26 May 2011, 14:51 last edited by
        #20

        Hmno, that was Andre's suggestion. Read "Gerolf's suggestion":https://developer.qt.nokia.com/forums/viewreply/33804/ again.

        "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

        http://www.catb.org/~esr/faqs/smart-questions.html

        1 Reply Last reply
        0
        • J Offline
          J Offline
          JulienMaille
          wrote on 26 May 2011, 15:08 last edited by
          #21

          Yes your right, I will end up doing something like this if I don't find anything simpler.
          I'm now considering this:
          adding a new emit processEventsInMain() in the loop,
          and connect this signal in a blocking way to a slot of my main thread that will just consist in a processEvents() call.

          1 Reply Last reply
          0
          • G Offline
            G Offline
            giesbert
            wrote on 26 May 2011, 17:49 last edited by
            #22

            Nonono, bad idea. the queued signal will be called if the main thread enters the event loop, so that will not solve the problem, you will get others. Opening the event loop is not a good idea, you get asynchronous behavior where you don't expect it.

            What is wrong with the intermediate object? That also works with any kind of data. Simple but powerfull pattern:

            The object stores the current data (or perhaps the current and the last). It has a member bNewDataEmitted. If this value is false, a dataChanged signal is emitted and the value is set to true. On each consecutive call of set data, no signal is emitted until the value goes to false.

            Each getData sets the value to false, so a dataChanged can be emitted on next setData.

            Nokia Certified Qt Specialist.
            Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JulienMaille
              wrote on 26 May 2011, 19:37 last edited by
              #23

              [quote author="Gerolf" date="1306432144"]Nonono, bad idea. the queued signal will be called if the main thread enters the event loop, so that will not solve the problem, you will get others.[/quote] Even with a Qt::BlockingQueuedConnection?

              1 Reply Last reply
              0
              • F Offline
                F Offline
                Franzk
                wrote on 26 May 2011, 19:49 last edited by
                #24

                Yes. BlockingQueuedConnection just waits until the event loop has finished executing the slot. If the slot is starting an event loop, you are getting weird results. Different example, but same case: http://labs.qt.nokia.com/2010/02/23/unpredictable-exec/.

                "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

                http://www.catb.org/~esr/faqs/smart-questions.html

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on 27 May 2011, 08:08 last edited by
                  #25

                  Is there really no way to know if you need to act on the result of your longProcess or not? So far, it is not very clear what your long process entains. You started out with a string (I guess as an example), and you are talking about pointers to images. However, you also said that sometimes your longProcess returns very very quick. Does it still return valid and new data if that happens?

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    JulienMaille
                    wrote on 27 May 2011, 09:31 last edited by
                    #26

                    My veryLongProcess() performs segmentation on an image.
                    If it work the result is an image with an overlay, if it fails it returns the original image.
                    In both cases it will also result a string containing some timers and error codes.

                    The original image comes from a live camera, so the output should be as real-time as possible.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on 27 May 2011, 09:35 last edited by
                      #27

                      So... couldn't you parse the error codes to see if you need to emit, and if so, what?

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        JulienMaille
                        wrote on 27 May 2011, 09:38 last edited by
                        #28

                        I always need to emit, even if it's an error I will emit the original image, the timers and the error code ...

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          andre
                          wrote on 27 May 2011, 09:48 last edited by
                          #29

                          Then, sorry, I don't know how to optimize further. I would say that at most, you'd need to emit a signal every 1/60th of a second (and probably half that or even only every 1/24th of a second), but if you say that you need to draw everything, then I believe you.

                          I think that if you really need to pass information that fast, that threads may not be the ideal way to do it. It also depends on how much time processing the information at the other end takes. I mean: it doesn't make much sense to send a load of new images to display as a video if the system is still busy with drawing the first image. That will only clog the event queue, which will result in even more delays.

                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            JulienMaille
                            wrote on 21 Jun 2011, 17:13 last edited by
                            #30

                            I tried to implement Andre's suggestion:
                            Since I can send many signals I added a int _sentSignals to my class:
                            @
                            private:
                            QMutex canEmitMutex;
                            int _sentSignals; //!< Safe-guard to avoid signal deluge
                            bool canEmit() {return _sentSignals<=0;}

                            public:
                            void signalProcessed();
                            void signalEmited();

                            // cpp
                            void ProcessingThread::signalProcessed()
                            {
                            canEmitMutex.lock();
                            _sentSignals--;
                            canEmitMutex.unlock();
                            }

                            void ProcessingThread::signalEmited()
                            {
                            canEmitMutex.lock();
                            _sentSignals++;
                            canEmitMutex.unlock();
                            }@

                            And now in my processing loop I have
                            @
                            while( someCondition )
                            {
                            iCanEmit = canEmit();

                            //code
                            if( iCanEmit )
                            {
                            emit someSignal();
                            signalEmited();
                            }
                            //repeat for other signals
                            }@

                            someSignal is connected to a slot in my main:
                            @
                            void MainWindow::slotDisplayStatusMsg(QString text)
                            {
                            ui->statusLabel->setText(text);
                            // Tell processing thread that we processed its signal
                            if( _procThread ) _procThread->signalProcessed();
                            }@

                            The problem is that, sometimes, some slot seems to be not executed. Hence _signalSent is not decremented and stays to 1. And my loop stop emiting.
                            Is it possible that some events are sometimes ignored?

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              giesbert
                              wrote on 21 Jun 2011, 18:59 last edited by
                              #31

                              no, it can't.
                              but between canEmit and signalEmitted in your while loop, there is a whole, where your raise condition may happen.
                              So I suggets doing it like this:

                              @
                              class ProcessingThread
                              {
                              private:
                              QMutex canEmitMutex;
                              int _sentSignals; //!< Safe-guard to avoid signal deluge
                              bool canEmit() {return _sentSignals<=0;}
                              // some more stuff

                              public:
                              // some more stuff
                              void signalProcessed();
                              };

                              void ProcessingThread::signalProcessed()
                              {
                              QMutexLocker lockObj(&canEmitMutex);
                              _sentSignals--;
                              }

                              void ProcessingThread::run()
                              {
                              // do some stuff
                              while( someCondition )
                              {
                              // emit lock
                              {
                              QMutexLocker lockObj(&canEmitMutex);
                              if(canEmit())
                              {
                              emit someSignal();
                              _sentSignals++;
                              }
                              }
                              }
                              // do some stuff
                              }
                              @

                              EDIT: corrected code, Gerolf

                              Nokia Certified Qt Specialist.
                              Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                JulienMaille
                                wrote on 21 Jun 2011, 22:30 last edited by
                                #32

                                Thanks for your help. Will try that tomorrow.
                                Hum, in your example I guess I should replace:
                                @void ProcessingThread::signalEmited()
                                {
                                QMutexLocker lockObj(&canEmitMutex);
                                _sentSignals++;
                                }@ with
                                @void ProcessingThread::signalProcessed()
                                {
                                QMutexLocker lockObj(&canEmitMutex);
                                _sentSignals--;
                                }@

                                1 Reply Last reply
                                0
                                • G Offline
                                  G Offline
                                  giesbert
                                  wrote on 22 Jun 2011, 06:22 last edited by
                                  #33

                                  perhaps, yes, it was late :-)

                                  Nokia Certified Qt Specialist.
                                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                  1 Reply Last reply
                                  0
                                  • G Offline
                                    G Offline
                                    giesbert
                                    wrote on 22 Jun 2011, 06:24 last edited by
                                    #34

                                    You could even use a boolean variable, as you only emit once....

                                    Nokia Certified Qt Specialist.
                                    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                    1 Reply Last reply
                                    0
                                    • J Offline
                                      J Offline
                                      JulienMaille
                                      wrote on 22 Jun 2011, 07:14 last edited by
                                      #35

                                      No in fact I emit more than once, I just simplified my sample code.

                                      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