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. QTimer::singleShot()'s syntax
Forum Updated to NodeBB v4.3 + New Features

QTimer::singleShot()'s syntax

Scheduled Pinned Locked Moved Solved General and Desktop
34 Posts 9 Posters 12.0k Views 4 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.
  • A Offline
    A Offline
    agarny
    wrote on last edited by
    #1

    Hi,

    I have recently updated the code of my project to use the new signal/slot syntax, and did this for my calls to QTimer::singleShot().

    Thus, I replaced something like:

    QTimer::singleShot(0, this, SLOT(callCheckSimulationResults()));
    

    with:

    QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
    

    Now, the problem with the new syntax is that I have found that my callCheckSimulationResults() method doesn't get called as often as it does using the old syntax. So, are the two syntaxes different or are they supposed to be exactly the same?...

    For a bit of context, you may want to check a GitHub issue that I created for my project. As for the code where that single shot is done, you can find it here.

    Thanks in advance for any help/suggestion,

    Alan

    JKSHJ JonBJ 2 Replies Last reply
    1
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      in regards to Qtimer sending the signal, there is absolutely zero
      difference between the 2 syntax's.

      So its something else if your slot is called less often than before. (IMHO)

      The new syntax provides compile time check of the connection and allows to connects to lambdas/callables. Its recommended to use. The only downside to new syntax is
      eye hurting ugly casts if the signals are overloaded.

      1 Reply Last reply
      4
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #3

        From https://github.com/opencor/opencor/blob/55718f183f498cf21793897f5772d52144c2350f/src/plugins/simulation/SimulationExperimentView/src/simulationexperimentviewwidget.cpp#L543

        we cannot ask QTimer::singleShot() to call checkSimulationResults() directly since it expects a file name

        You can with Qt5 and this is the root of your problem. checkSimulationResults always uses the first() result but there's nothing assuring you every results is first() at least once.

        • delete callCheckSimulationResults completely
        • Replace QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
          with QTimer::singleShot(0, this, std::bind(&SimulationExperimentViewWidget::checkSimulationResults,this,pFileName,SimulationExperimentViewSimulationWidget::None));

        "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
        6
        • A Offline
          A Offline
          agarny
          wrote on last edited by
          #4

          @mrjj: I am more than happy to accept that there may be something else that is "wrong" in my code. However, all I did in my code was replace one syntax with another. I didn't change anything else, just the call to the single shot, as mentioned in my original message. Yet, the behaviour I am getting is clearly different (and definitely reproducible). So, why?

          @VRonin: thanks, I have just given it a try and I can indeed confirm that it works, but I am getting the same behaviour than I am getting when using the new signal/slot syntax. In other words, I am not getting the same behaviour that I am getting using the old syntax. So, it doesn't seem to be the root of my problem.

          1 Reply Last reply
          0
          • A agarny

            Hi,

            I have recently updated the code of my project to use the new signal/slot syntax, and did this for my calls to QTimer::singleShot().

            Thus, I replaced something like:

            QTimer::singleShot(0, this, SLOT(callCheckSimulationResults()));
            

            with:

            QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
            

            Now, the problem with the new syntax is that I have found that my callCheckSimulationResults() method doesn't get called as often as it does using the old syntax. So, are the two syntaxes different or are they supposed to be exactly the same?...

            For a bit of context, you may want to check a GitHub issue that I created for my project. As for the code where that single shot is done, you can find it here.

            Thanks in advance for any help/suggestion,

            Alan

            JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by JKSH
            #5

            @agarny said in QTimer::singleShot()'s syntax:

            Now, the problem with the new syntax is that I have found that my callCheckSimulationResults() method doesn't get called as often as it does using the old syntax.

            What do you mean by "doesn't get called as often"? How often are you firing single-shot timers?

            Place a qDebug() call just before each call to QTimer::singleShot() and run your code to see if that reveals any clues. Do this using both the new and old syntaxes.

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            1 Reply Last reply
            0
            • A Offline
              A Offline
              agarny
              wrote on last edited by
              #6

              @JKSH: I mean that, using the old syntax, my slot might get called 100 times while, using the new syntax, it might only get called 80 times. FWIW, I use that single slot mechanism to output simulation data that is being generated on the fly. In other words, my slot checks whether new simulation data is available and, if so, plots it.

              Using the old syntax, everything gets plotted:

              alt text

              while using the new syntax, only some of my simulation data gets plotted:

              alt text

              Just look at the blue traces at the top. The beginning of those traces is plotted, but the end of them is not always plotted, and that is a direct consequence of the new syntax.

              Regarding your suggestion, it's not that simple since the frequency of those calls to QTimer::singleShot() depends on how busy my computer is when running a simulation. All I can say is that using the old syntax, all my traces are full while, using the new syntax, some of them are full some not.

              J.HilkJ JKSHJ 2 Replies Last reply
              0
              • A agarny

                @JKSH: I mean that, using the old syntax, my slot might get called 100 times while, using the new syntax, it might only get called 80 times. FWIW, I use that single slot mechanism to output simulation data that is being generated on the fly. In other words, my slot checks whether new simulation data is available and, if so, plots it.

                Using the old syntax, everything gets plotted:

                alt text

                while using the new syntax, only some of my simulation data gets plotted:

                alt text

                Just look at the blue traces at the top. The beginning of those traces is plotted, but the end of them is not always plotted, and that is a direct consequence of the new syntax.

                Regarding your suggestion, it's not that simple since the frequency of those calls to QTimer::singleShot() depends on how busy my computer is when running a simulation. All I can say is that using the old syntax, all my traces are full while, using the new syntax, some of them are full some not.

                J.HilkJ Online
                J.HilkJ Online
                J.Hilk
                Moderators
                wrote on last edited by
                #7

                @agarny mmh,
                have you tried this with QTimer as a class member?
                I would imagin that creating a QTimer-object a 100 times per second is a heavy task, and comes with a cost.


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                A 1 Reply Last reply
                1
                • A agarny

                  @JKSH: I mean that, using the old syntax, my slot might get called 100 times while, using the new syntax, it might only get called 80 times. FWIW, I use that single slot mechanism to output simulation data that is being generated on the fly. In other words, my slot checks whether new simulation data is available and, if so, plots it.

                  Using the old syntax, everything gets plotted:

                  alt text

                  while using the new syntax, only some of my simulation data gets plotted:

                  alt text

                  Just look at the blue traces at the top. The beginning of those traces is plotted, but the end of them is not always plotted, and that is a direct consequence of the new syntax.

                  Regarding your suggestion, it's not that simple since the frequency of those calls to QTimer::singleShot() depends on how busy my computer is when running a simulation. All I can say is that using the old syntax, all my traces are full while, using the new syntax, some of them are full some not.

                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by JKSH
                  #8

                  @agarny said in QTimer::singleShot()'s syntax:

                  Just look at the blue traces at the top. The beginning of those traces is plotted, but the end of them is not always plotted, and that is a direct consequence of the new syntax.

                  Understood. The traces show symptoms of the pathology, but it reveals very little about the mechanism of the pathology.

                  We expect both syntaxes to perform exactly the same functions. We don't expect them to behave exactly the same under the hood though, because the old syntax involves searching a list of strings to find your slot, whereas the new syntax simply stores a function pointer to your slot. I expect the new syntax to be marginally more efficient so your computer should be marginally less "busy" during the simulation.

                  Some possible mechanisms I can think of (without reverse-engineering your whole project) are:

                  1. There's a bug in QTimer.
                    • It sometimes fails to trigger as instructed.
                  2. There's a race condition in your code.
                    • When you switched to the new syntax, its different behaviour under-the-hood caused the timings of different parts of your program to change relative to each other, which broke an assumption about execution order. Consequently, your code sometimes doesn't initialize a new single-shot timer when it should.
                    • Perhaps your code no longer gives the file enough time to be finalized before trying to read it again?

                  Regarding your suggestion, it's not that simple since the frequency of those calls to QTimer::singleShot() depends on how busy my computer is when running a simulation.

                  Then do your best to make your computer's busy-ness as uniform as possible during different trials -- just close all other programs and run this one only. Like in cell biology, it doesn't matter if each trial isn't exactly the same. As long as their environments are similar enough, they will still let you identify trends/patterns.

                  It's straightforward to check if mechanism #1 is responsible or not: Add qDebug("PING"); just before QTimer::singleShot() and add qDebug("\tPONG"); to the top of callCheckSimulationResults().

                  • If the number of PINGs is greater than the number of PONGs, that strongly suggests a bug in QTimer.
                  • If there are equal numbers of PINGs and PONGs, yet you still see truncated waveforms, then I'd suspect a bug in your code.

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  A 1 Reply Last reply
                  1
                  • J.HilkJ J.Hilk

                    @agarny mmh,
                    have you tried this with QTimer as a class member?
                    I would imagin that creating a QTimer-object a 100 times per second is a heavy task, and comes with a cost.

                    A Offline
                    A Offline
                    agarny
                    wrote on last edited by
                    #9

                    @J.Hilk: do you mean something like:

                    static QTimer timer;
                    
                    timer.singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
                    

                    If so, I have just given it a try, but to no avail (some traces are still incomplete) while, as you would, expect:

                    static QTimer timer;
                    timer.singleShot(0, this, SLOT(callCheckSimulationResults()));
                    

                    works fine.

                    J.HilkJ 1 Reply Last reply
                    0
                    • JKSHJ JKSH

                      @agarny said in QTimer::singleShot()'s syntax:

                      Just look at the blue traces at the top. The beginning of those traces is plotted, but the end of them is not always plotted, and that is a direct consequence of the new syntax.

                      Understood. The traces show symptoms of the pathology, but it reveals very little about the mechanism of the pathology.

                      We expect both syntaxes to perform exactly the same functions. We don't expect them to behave exactly the same under the hood though, because the old syntax involves searching a list of strings to find your slot, whereas the new syntax simply stores a function pointer to your slot. I expect the new syntax to be marginally more efficient so your computer should be marginally less "busy" during the simulation.

                      Some possible mechanisms I can think of (without reverse-engineering your whole project) are:

                      1. There's a bug in QTimer.
                        • It sometimes fails to trigger as instructed.
                      2. There's a race condition in your code.
                        • When you switched to the new syntax, its different behaviour under-the-hood caused the timings of different parts of your program to change relative to each other, which broke an assumption about execution order. Consequently, your code sometimes doesn't initialize a new single-shot timer when it should.
                        • Perhaps your code no longer gives the file enough time to be finalized before trying to read it again?

                      Regarding your suggestion, it's not that simple since the frequency of those calls to QTimer::singleShot() depends on how busy my computer is when running a simulation.

                      Then do your best to make your computer's busy-ness as uniform as possible during different trials -- just close all other programs and run this one only. Like in cell biology, it doesn't matter if each trial isn't exactly the same. As long as their environments are similar enough, they will still let you identify trends/patterns.

                      It's straightforward to check if mechanism #1 is responsible or not: Add qDebug("PING"); just before QTimer::singleShot() and add qDebug("\tPONG"); to the top of callCheckSimulationResults().

                      • If the number of PINGs is greater than the number of PONGs, that strongly suggests a bug in QTimer.
                      • If there are equal numbers of PINGs and PONGs, yet you still see truncated waveforms, then I'd suspect a bug in your code.
                      A Offline
                      A Offline
                      agarny
                      wrote on last edited by
                      #10

                      @JKSH: the data I am plotting doesn't come from a file, but is computed and then stored in memory. So, all my program does (through that single shot) is check whether new data is available and, if so, plots it.

                      Regarding your suggestion, it's not that simple since the frequency of those calls to QTimer::singleShot() depends on how busy my computer is when running a simulation.

                      Then do your best to make your computer's busy-ness as uniform as possible during different trials -- just close all other programs and run this one only. Like in cell biology, it doesn't matter if each trial isn't exactly the same. As long as their environments are similar enough, they will still let you identify trends/patterns.

                      Actually, I should take that comment back since my computer's CPU load is not that different when trying the old or new syntax.

                      It's straightforward to check if mechanism #1 is responsible or not: Add qDebug("PING"); just before QTimer::singleShot() and add qDebug("\tPONG"); to the top of callCheckSimulationResults().

                      • If the number of PINGs is greater than the number of PONGs, that strongly suggests a bug in QTimer.
                      • If there are equal numbers of PINGs and PONGs, yet you still see truncated waveforms, then I'd suspect a bug in your code.

                      I just had a quick go at it and the number of PINGs and PONGs is the same whether I use the old or new syntax. So, QTimer::singleShot() works as expected. However, there are more PINGs/PONGs using the old syntax than the new one, and I am not sure why yet...

                      JKSHJ 1 Reply Last reply
                      0
                      • A agarny

                        @J.Hilk: do you mean something like:

                        static QTimer timer;
                        
                        timer.singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
                        

                        If so, I have just given it a try, but to no avail (some traces are still incomplete) while, as you would, expect:

                        static QTimer timer;
                        timer.singleShot(0, this, SLOT(callCheckSimulationResults()));
                        

                        works fine.

                        J.HilkJ Online
                        J.HilkJ Online
                        J.Hilk
                        Moderators
                        wrote on last edited by J.Hilk
                        #11

                        @agarny

                        Not quite what I had in mind.
                        I meant something like this:

                        //.h
                        QTimer myTimer;
                        
                        //.cpp constructor
                        {
                           myTimer.setSingleShot(true);
                           myTimer.setInterval(0); 
                           connect(&myTimer, &QTimer::timeout, &SimulationExperimentViewWidget::callCheckSimulationResults);
                        }
                        

                        and later in your code:

                        myTimer.start();
                        

                        edit:

                        actually, you could also try a connect via MetaObject::invokeMethod, see how that behaves:

                        #if QT_VERSION >= 0x50a00
                        QMetaObject::invokeMethod(this, &SimulationExperimentViewWidget::callCheckSimulationResults,Qt::QueuedConnection);
                        #else
                        QMetaObject::invokeMethod(this,"callCheckSimulationResults",Qt::QueuedConnection);
                        #endif
                        

                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        A 1 Reply Last reply
                        2
                        • J.HilkJ J.Hilk

                          @agarny

                          Not quite what I had in mind.
                          I meant something like this:

                          //.h
                          QTimer myTimer;
                          
                          //.cpp constructor
                          {
                             myTimer.setSingleShot(true);
                             myTimer.setInterval(0); 
                             connect(&myTimer, &QTimer::timeout, &SimulationExperimentViewWidget::callCheckSimulationResults);
                          }
                          

                          and later in your code:

                          myTimer.start();
                          

                          edit:

                          actually, you could also try a connect via MetaObject::invokeMethod, see how that behaves:

                          #if QT_VERSION >= 0x50a00
                          QMetaObject::invokeMethod(this, &SimulationExperimentViewWidget::callCheckSimulationResults,Qt::QueuedConnection);
                          #else
                          QMetaObject::invokeMethod(this,"callCheckSimulationResults",Qt::QueuedConnection);
                          #endif
                          
                          A Offline
                          A Offline
                          agarny
                          wrote on last edited by
                          #12

                          @J.Hilk: ok, I have given your QTimer as a class member suggestion a go and some traces are incomplete, both using the old or new connect syntax, although it's (still) worse using the new syntax.

                          Well, I am using Qt 5.9.4, so I am not able to test

                          QMetaObject::invokeMethod(this, &SimulationExperimentViewWidget::callCheckSimulationResults, Qt::QueuedConnection);
                          

                          but

                          QMetaObject::invokeMethod(this, &SimulationExperimentViewWidget::callCheckSimulationResults, Qt::QueuedConnection);
                          

                          works as expected, but I imagine that it's not surprising. It's the other syntax that would be interesting to check.

                          1 Reply Last reply
                          0
                          • A agarny

                            @JKSH: the data I am plotting doesn't come from a file, but is computed and then stored in memory. So, all my program does (through that single shot) is check whether new data is available and, if so, plots it.

                            Regarding your suggestion, it's not that simple since the frequency of those calls to QTimer::singleShot() depends on how busy my computer is when running a simulation.

                            Then do your best to make your computer's busy-ness as uniform as possible during different trials -- just close all other programs and run this one only. Like in cell biology, it doesn't matter if each trial isn't exactly the same. As long as their environments are similar enough, they will still let you identify trends/patterns.

                            Actually, I should take that comment back since my computer's CPU load is not that different when trying the old or new syntax.

                            It's straightforward to check if mechanism #1 is responsible or not: Add qDebug("PING"); just before QTimer::singleShot() and add qDebug("\tPONG"); to the top of callCheckSimulationResults().

                            • If the number of PINGs is greater than the number of PONGs, that strongly suggests a bug in QTimer.
                            • If there are equal numbers of PINGs and PONGs, yet you still see truncated waveforms, then I'd suspect a bug in your code.

                            I just had a quick go at it and the number of PINGs and PONGs is the same whether I use the old or new syntax. So, QTimer::singleShot() works as expected. However, there are more PINGs/PONGs using the old syntax than the new one, and I am not sure why yet...

                            JKSHJ Offline
                            JKSHJ Offline
                            JKSH
                            Moderators
                            wrote on last edited by JKSH
                            #13

                            @agarny said in QTimer::singleShot()'s syntax:

                            I have given your QTimer as a class member suggestion a go and some traces are incomplete, both using the old or new connect syntax, although it's (still) worse using the new syntax.

                            • Your original code has the most overhead.
                            • The member-QTimer with old syntax has moderate overhead.
                            • The member-QTimer with new syntax has the least overhead.

                            Greater overhead means greater delays in triggering the slot, and greater delays seem to result in greater reliability in your plots. This strongly suggests to me that your code has a race condition.

                            If this is the case, then simply upgrading to a more powerful computer can give you incomplete traces too, even with your original code with old syntax.

                            @agarny said in QTimer::singleShot()'s syntax:

                            I just had a quick go at it and the number of PINGs and PONGs is the same whether I use the old or new syntax. So, QTimer::singleShot() works as expected. However, there are more PINGs/PONGs using the old syntax than the new one, and I am not sure why yet...

                            With the PING/PONG test in place, did you see any truncated waveforms?

                            Next, I'd investigate to see why fewer PINGs are being generated. I'm guessing your last if() is not entering the right case, so I'd probe that:

                            if (simulation->isRunning() || (simulationResultsSize != simulation->results()->size())) {
                                mSimulationCheckResults << pFileName;
                                qDebug() << "PING" << pFileName;
                                QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
                            } else if (!simulation->isRunning() && !simulation->isPaused()) {
                                qDebug("\tEND");
                                mSimulationResultsSizes.remove(pFileName);
                                simulationWidget->resetSimulationProgress();
                            } else {
                                qDebug("\t???");
                            }
                            

                            Other things that might be worth investigating:

                            • Log the values of simulationResultsSize and mSimulationResultsSizes.value(pFileName) every call. Look for differences in values when you switch syntaxes.
                            • Log the times of every call, using QTime::currentTime() or QElapsedTimer::elapsed() (the latter needs a member object). Look for differences in values when you switch syntaxes.

                            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                            A 1 Reply Last reply
                            3
                            • A agarny

                              Hi,

                              I have recently updated the code of my project to use the new signal/slot syntax, and did this for my calls to QTimer::singleShot().

                              Thus, I replaced something like:

                              QTimer::singleShot(0, this, SLOT(callCheckSimulationResults()));
                              

                              with:

                              QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
                              

                              Now, the problem with the new syntax is that I have found that my callCheckSimulationResults() method doesn't get called as often as it does using the old syntax. So, are the two syntaxes different or are they supposed to be exactly the same?...

                              For a bit of context, you may want to check a GitHub issue that I created for my project. As for the code where that single shot is done, you can find it here.

                              Thanks in advance for any help/suggestion,

                              Alan

                              JonBJ Offline
                              JonBJ Offline
                              JonB
                              wrote on last edited by
                              #14

                              @agarny said in QTimer::singleShot()'s syntax:

                              I have recently updated the code of my project to use the new signal/slot syntax, and did this for my calls to QTimer::singleShot().

                              Just to absolutely clear (although you do seem to know what you are talking about, so this is perhaps obvious to you), given you are making this change:

                              • You're not doing the change against a different version/compilation of Qt, are you?
                              • Given that you are "cleaning up" code, there aren't any other changes to your code, are there?
                              A 1 Reply Last reply
                              1
                              • JKSHJ JKSH

                                @agarny said in QTimer::singleShot()'s syntax:

                                I have given your QTimer as a class member suggestion a go and some traces are incomplete, both using the old or new connect syntax, although it's (still) worse using the new syntax.

                                • Your original code has the most overhead.
                                • The member-QTimer with old syntax has moderate overhead.
                                • The member-QTimer with new syntax has the least overhead.

                                Greater overhead means greater delays in triggering the slot, and greater delays seem to result in greater reliability in your plots. This strongly suggests to me that your code has a race condition.

                                If this is the case, then simply upgrading to a more powerful computer can give you incomplete traces too, even with your original code with old syntax.

                                @agarny said in QTimer::singleShot()'s syntax:

                                I just had a quick go at it and the number of PINGs and PONGs is the same whether I use the old or new syntax. So, QTimer::singleShot() works as expected. However, there are more PINGs/PONGs using the old syntax than the new one, and I am not sure why yet...

                                With the PING/PONG test in place, did you see any truncated waveforms?

                                Next, I'd investigate to see why fewer PINGs are being generated. I'm guessing your last if() is not entering the right case, so I'd probe that:

                                if (simulation->isRunning() || (simulationResultsSize != simulation->results()->size())) {
                                    mSimulationCheckResults << pFileName;
                                    qDebug() << "PING" << pFileName;
                                    QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
                                } else if (!simulation->isRunning() && !simulation->isPaused()) {
                                    qDebug("\tEND");
                                    mSimulationResultsSizes.remove(pFileName);
                                    simulationWidget->resetSimulationProgress();
                                } else {
                                    qDebug("\t???");
                                }
                                

                                Other things that might be worth investigating:

                                • Log the values of simulationResultsSize and mSimulationResultsSizes.value(pFileName) every call. Look for differences in values when you switch syntaxes.
                                • Log the times of every call, using QTime::currentTime() or QElapsedTimer::elapsed() (the latter needs a member object). Look for differences in values when you switch syntaxes.
                                A Offline
                                A Offline
                                agarny
                                wrote on last edited by
                                #15

                                @JKSH said in QTimer::singleShot()'s syntax:

                                @agarny said in QTimer::singleShot()'s syntax:

                                I have given your QTimer as a class member suggestion a go and some traces are incomplete, both using the old or new connect syntax, although it's (still) worse using the new syntax.

                                • Your original code has the most overhead.
                                • The member-QTimer with old syntax has moderate overhead.
                                • The member-QTimer with new syntax has the least overhead.

                                Greater overhead means greater delays in triggering the slot, and greater delays seem to result in greater reliability in your plots. This strongly suggests to me that your code has a race condition.

                                Yes, I have just done some tests timing the interval with which my single shots are called and the intervals are greater with the old syntax.

                                If this is the case, then simply upgrading to a more powerful computer can give you incomplete traces too, even with your original code with old syntax.

                                I am happy to believe that, now that I have got those intervals.

                                With the PING/PONG test in place, did you see any truncated waveforms?

                                Yes, I did. In fact, looking at the plots I got, I couldn't tell the difference with or without the PING/PONG test.

                                1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @agarny said in QTimer::singleShot()'s syntax:

                                  I have recently updated the code of my project to use the new signal/slot syntax, and did this for my calls to QTimer::singleShot().

                                  Just to absolutely clear (although you do seem to know what you are talking about, so this is perhaps obvious to you), given you are making this change:

                                  • You're not doing the change against a different version/compilation of Qt, are you?
                                  • Given that you are "cleaning up" code, there aren't any other changes to your code, are there?
                                  A Offline
                                  A Offline
                                  agarny
                                  wrote on last edited by
                                  #16

                                  @JonB said in QTimer::singleShot()'s syntax:

                                  @agarny said in QTimer::singleShot()'s syntax:

                                  I have recently updated the code of my project to use the new signal/slot syntax, and did this for my calls to QTimer::singleShot().

                                  Just to absolutely clear (although you do seem to know what you are talking about, so this is perhaps obvious to you), given you are making this change:

                                  • You're not doing the change against a different version/compilation of Qt, are you?
                                  • Given that you are "cleaning up" code, there aren't any other changes to your code, are there?

                                  Indeed, I am using the same version of Qt (5.9.4) with both the old and new syntax. In fact, when it comes to this thread, the only thing I have done to my code is using either:

                                  QTimer::singleShot(0, this, SLOT(callCheckSimulationResults()));
                                  

                                  or

                                  QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
                                  

                                  The rest of my code is exactly the same.

                                  kshegunovK 1 Reply Last reply
                                  1
                                  • A agarny

                                    @JonB said in QTimer::singleShot()'s syntax:

                                    @agarny said in QTimer::singleShot()'s syntax:

                                    I have recently updated the code of my project to use the new signal/slot syntax, and did this for my calls to QTimer::singleShot().

                                    Just to absolutely clear (although you do seem to know what you are talking about, so this is perhaps obvious to you), given you are making this change:

                                    • You're not doing the change against a different version/compilation of Qt, are you?
                                    • Given that you are "cleaning up" code, there aren't any other changes to your code, are there?

                                    Indeed, I am using the same version of Qt (5.9.4) with both the old and new syntax. In fact, when it comes to this thread, the only thing I have done to my code is using either:

                                    QTimer::singleShot(0, this, SLOT(callCheckSimulationResults()));
                                    

                                    or

                                    QTimer::singleShot(0, this, &SimulationExperimentViewWidget::callCheckSimulationResults);
                                    

                                    The rest of my code is exactly the same.

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by kshegunov
                                    #17

                                    https://github.com/opencor/opencor/blob/master/src/plugins/support/SimulationSupport/src/simulationworker.cpp#L199

                                    Your threading is all jumbled up, you can't just read and modify fields from objects that are in different threads ... if it works, it's the hand of god, if it doesn't work, it's the hand of god as well ... (and that one comes from an atheist)

                                    To give you a straightforwardly obvious example:
                                    https://github.com/opencor/opencor/blob/master/src/plugins/support/SimulationSupport/src/simulationworker.cpp#L95

                                    What's guarding mCurrentPoint?
                                    I would also imagine you may get a lot of runtime warnings from Qt about objects being created before QApplication (due to singletons) and possibly also warnings about destruction order or destructions from different threads.

                                    Read and abide by the Qt Code of Conduct

                                    A 2 Replies Last reply
                                    7
                                    • kshegunovK kshegunov

                                      https://github.com/opencor/opencor/blob/master/src/plugins/support/SimulationSupport/src/simulationworker.cpp#L199

                                      Your threading is all jumbled up, you can't just read and modify fields from objects that are in different threads ... if it works, it's the hand of god, if it doesn't work, it's the hand of god as well ... (and that one comes from an atheist)

                                      To give you a straightforwardly obvious example:
                                      https://github.com/opencor/opencor/blob/master/src/plugins/support/SimulationSupport/src/simulationworker.cpp#L95

                                      What's guarding mCurrentPoint?
                                      I would also imagine you may get a lot of runtime warnings from Qt about objects being created before QApplication (due to singletons) and possibly also warnings about destruction order or destructions from different threads.

                                      A Offline
                                      A Offline
                                      agarny
                                      wrote on last edited by
                                      #18

                                      @kshegunov: yes, I think it's starting to become very clear that I am facing a race condition and that I have been pretty lucky these past few years. Ok, I guess I am going to have to check that very carefully. (In the end, it's a good thing that I decided to use the new syntax... (Positive thinking... :))

                                      1 Reply Last reply
                                      3
                                      • kshegunovK kshegunov

                                        https://github.com/opencor/opencor/blob/master/src/plugins/support/SimulationSupport/src/simulationworker.cpp#L199

                                        Your threading is all jumbled up, you can't just read and modify fields from objects that are in different threads ... if it works, it's the hand of god, if it doesn't work, it's the hand of god as well ... (and that one comes from an atheist)

                                        To give you a straightforwardly obvious example:
                                        https://github.com/opencor/opencor/blob/master/src/plugins/support/SimulationSupport/src/simulationworker.cpp#L95

                                        What's guarding mCurrentPoint?
                                        I would also imagine you may get a lot of runtime warnings from Qt about objects being created before QApplication (due to singletons) and possibly also warnings about destruction order or destructions from different threads.

                                        A Offline
                                        A Offline
                                        agarny
                                        wrote on last edited by
                                        #19

                                        @kshegunov: by the way, no, I am not getting any runtime warnings from Qt.

                                        kshegunovK 1 Reply Last reply
                                        0
                                        • A agarny

                                          @kshegunov: by the way, no, I am not getting any runtime warnings from Qt.

                                          kshegunovK Offline
                                          kshegunovK Offline
                                          kshegunov
                                          Moderators
                                          wrote on last edited by
                                          #20

                                          a race condition

                                          More than one, I noticed at least several in that particular file.

                                          by the way, no, I am not getting any runtime warnings from Qt.

                                          I said you may, not that you are going to, as I didn't check the whole source. I spotted a place or two where you use the singleton, so that's usually accompanied by such warnings.

                                          Read and abide by the Qt Code of Conduct

                                          A 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