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. Why "standard " Linux sleep(x) - as defined in uinstd.h does not work as expected ?
Forum Update on Monday, May 27th 2025

Why "standard " Linux sleep(x) - as defined in uinstd.h does not work as expected ?

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 4 Posters 691 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.
  • A Offline
    A Offline
    Anonymous_Banned275
    wrote on last edited by
    #1

    I expect the following code to output "step one" , then wait 15 seconds before outputting next steps.

    It waits for 15 seconds then outputs all at once.

    Any reason ?

    #include <unistd.h>
    ui->plainTextEdit_4->setPlainText("STEP ONE INFO NAME ");
    sleep(15);
    ui->plainTextEdit_4->appendPlainText("STEP two INFO NAME ");
    discoveryAgent->start();
    ui->plainTextEdit_4->appendPlainText("STEP three INFO NAME ");

    JonBJ 1 Reply Last reply
    0
    • Kent-DorfmanK Offline
      Kent-DorfmanK Offline
      Kent-Dorfman
      wrote on last edited by Kent-Dorfman
      #3

      never use sleep() in a QObject derived class. The QObject class has its own event loop and sleep() interferes with its ability to process events. It's also an innaccurate delay mechanism because it can be woken up by a signal, and it may delay "longer" than the requested interval.

      A 1 Reply Last reply
      4
      • A Anonymous_Banned275

        I expect the following code to output "step one" , then wait 15 seconds before outputting next steps.

        It waits for 15 seconds then outputs all at once.

        Any reason ?

        #include <unistd.h>
        ui->plainTextEdit_4->setPlainText("STEP ONE INFO NAME ");
        sleep(15);
        ui->plainTextEdit_4->appendPlainText("STEP two INFO NAME ");
        discoveryAgent->start();
        ui->plainTextEdit_4->appendPlainText("STEP three INFO NAME ");

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

        @AnneRanch
        Because the widget is not shown as updated after setPlainText() till the event loop is hit. Which doesn't happen while sleep(15); is executing, only afterward. The sleep() itself is working as documented. You must not use sleep(), you need to use a QTimer() (Qtimer::singleShot() in this case).

        1 Reply Last reply
        5
        • Kent-DorfmanK Offline
          Kent-DorfmanK Offline
          Kent-Dorfman
          wrote on last edited by Kent-Dorfman
          #3

          never use sleep() in a QObject derived class. The QObject class has its own event loop and sleep() interferes with its ability to process events. It's also an innaccurate delay mechanism because it can be woken up by a signal, and it may delay "longer" than the requested interval.

          A 1 Reply Last reply
          4
          • Kent-DorfmanK Kent-Dorfman

            never use sleep() in a QObject derived class. The QObject class has its own event loop and sleep() interferes with its ability to process events. It's also an innaccurate delay mechanism because it can be woken up by a signal, and it may delay "longer" than the requested interval.

            A Offline
            A Offline
            Anonymous_Banned275
            wrote on last edited by
            #4

            @Kent-Dorfman said in Why "standard " Linux sleep(x) - as defined in uinstd.h does not work as expected ?:

            never use sleep() in a QObject derived class. The QObject class has its own event loop and sleep() interferes with its ability to process events. It's also an innaccurate delay mechanism because it can be woken up by a signal, and it may delay "longer" than the requested interval.

            Thanks, makes perfect sense.
            BUT ... the usual "but"

            is there a general documentation describing how this "event loop" works ?

            Is it similar to "thread / process " ?

            PS Accuracy in my case was irrelevant.

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

              Hi,

              QCoreApplication details
              QEventLoop

              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
              1
              • A Offline
                A Offline
                Anonymous_Banned275
                wrote on last edited by
                #6

                Here is my implementation of QTimer. It does not work as expected

                delay
                set first lines in plain text widget
                delay
                set second set of lines

                I get
                immediately second set of lines

                then 5 seconds later
                two consecutive "debug delay " outputs

                  if(1)
                    {
                        startHelloWave();      // 5 s delay 
                        ui->plainTextEdit_4->setPlainText("test delay ");
                        ui->plainTextEdit_4->appendPlainText("test delay ");
                
                        startHelloWave();   // 5 s delay 
                        ui->plainTextEdit_4->setPlainText("AFTER delay test delay ");
                        ui->plainTextEdit_4->appendPlainText("test delay ");
                
                    }
                    return;
                

                Application output

                void CCC_DiscoverDevice::on_checkBox_clicked(bool checked)
                5 seconds delay !
                5 seconds delay !
                /media/z/DEV_COPY_LABEL/Qt/QT/qtconnectivity/examples/bluetooth/build-CAT_BT-Desktop-Debug/btscanner exited with code 0

                QTimer code

                void CCC_DiscoverDevice::startHelloWave()
                {
                    timerDelay->singleShot(5 * 1000, this, SLOT(helloWave()));
                
                }
                
                void CCC_DiscoverDevice::helloWave()
                {
                    qDebug() << "5 seconds delay  !";
                    //timerDelay->singleShot(5 * 1000, this, SLOT(helloWave()));
                }
                
                
                

                What did I do wrong ?

                JonBJ 1 Reply Last reply
                0
                • Kent-DorfmanK Offline
                  Kent-DorfmanK Offline
                  Kent-Dorfman
                  wrote on last edited by
                  #7

                  You're thinking in sequential programming terms, not event driven. consider the timer an asynchronous background task, not a blocking task. Use the expired() slots to do "something" when the timer expires.

                  Your program in Qt is ALWAYS doing something. Anything you do that blocks will interfere with that process, so you MUST trigger things based on events happening, not an expecation that an operation will take some set amount of time.

                  1 Reply Last reply
                  4
                  • A Anonymous_Banned275

                    Here is my implementation of QTimer. It does not work as expected

                    delay
                    set first lines in plain text widget
                    delay
                    set second set of lines

                    I get
                    immediately second set of lines

                    then 5 seconds later
                    two consecutive "debug delay " outputs

                      if(1)
                        {
                            startHelloWave();      // 5 s delay 
                            ui->plainTextEdit_4->setPlainText("test delay ");
                            ui->plainTextEdit_4->appendPlainText("test delay ");
                    
                            startHelloWave();   // 5 s delay 
                            ui->plainTextEdit_4->setPlainText("AFTER delay test delay ");
                            ui->plainTextEdit_4->appendPlainText("test delay ");
                    
                        }
                        return;
                    

                    Application output

                    void CCC_DiscoverDevice::on_checkBox_clicked(bool checked)
                    5 seconds delay !
                    5 seconds delay !
                    /media/z/DEV_COPY_LABEL/Qt/QT/qtconnectivity/examples/bluetooth/build-CAT_BT-Desktop-Debug/btscanner exited with code 0

                    QTimer code

                    void CCC_DiscoverDevice::startHelloWave()
                    {
                        timerDelay->singleShot(5 * 1000, this, SLOT(helloWave()));
                    
                    }
                    
                    void CCC_DiscoverDevice::helloWave()
                    {
                        qDebug() << "5 seconds delay  !";
                        //timerDelay->singleShot(5 * 1000, this, SLOT(helloWave()));
                    }
                    
                    
                    

                    What did I do wrong ?

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

                    @AnneRanch

                    void CCC_DiscoverDevice::startHelloWave()
                    {
                        ui->plainTextEdit_4->setPlainText(QString("Hello: starting at time %1").arg(QTime::currentTime().toString("hh:mm:ss")));
                        timerDelay->singleShot(5 * 1000, this, &CCC_DiscoverDevice::helloWave);
                    }
                    
                    void CCC_DiscoverDevice::helloWave()
                    {
                        ui->plainTextEdit_4->setPlainText(QString("Goodbye: ending at time %1").arg(QTime::currentTime().toString("hh:mm:ss")));
                    }
                    

                    You must do the changing of the textedit in the slot which is called on timer expiry. That's how an event-driven system works.

                    1 Reply Last reply
                    2
                    • A Offline
                      A Offline
                      Anonymous_Banned275
                      wrote on last edited by
                      #9

                      Allow me reply with (positive) vent.
                      Yes, I build my first sequential application – in 1973 - coding in assembly.
                      I have selected Qt because I need a GUI , not because I need event driven IDE .
                      After trying (unsuccessfully) many Qt build-in examples I settled for QtDesigner wizard and build plain , basic “main window” . It worked as expected , even without SINGLE line code of comments. Yes, the “tooltips” are nice and very useful…
                      Some of the forum participants may have noticed that I have been posting few “ how does this work..” questions.
                      To my "defence" – the only computer book I have ever actually read from cover to cover was “K&R C programming language”. I only RTFM or ask Mrs Google about what is helping me to resolve an issue and most of the time my “problem” is in using wrong , unfamiliar terminology.
                      I see this discussion as THE MOST important and HELPFUL, in the series of my posts, and BEST conducted – in theory and in practice.
                      Important because it (finally) points out the fundamental concept of event driven software. ( Perhaps I should have pay more attention when using Windows).
                      Thanks
                      Cheers

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        Anonymous_Banned275
                        wrote on last edited by
                        #10

                        I am back...
                        Single delay works as advertised...

                        I need ONE more advise ... how do I cascade / loop the delays ?
                        In another words - how start another single shot?
                        Obviously my code is again sequential , hence wrong.
                        Eventually I will need delays in a loop - sending asynchronous data...

                        if(1)
                        {
                        //startHelloWave();
                        startHelloWave(); // display starting time
                        // return;

                           // QTimer::singleShot(5*1000, this, SLOT(quit()));
                            ui->plainTextEdit_4->appendPlainText("Initial test delay ");
                            ui->plainTextEdit_4->appendPlainText("test delay ");
                        
                           startHelloWave();     // another delay
                        
                            ui->plainTextEdit_4->appendPlainText("AFTER delay test delay ");
                            ui->plainTextEdit_4->appendPlainText("test delay ");
                        
                        }
                        return;
                        
                        JonBJ 1 Reply Last reply
                        0
                        • Kent-DorfmanK Offline
                          Kent-DorfmanK Offline
                          Kent-Dorfman
                          wrote on last edited by
                          #11

                          Within reason, you can start as many timers as you want to, all with different timeouts, if that is your intention. Another method for period based computing is to start a singel short interval timer that reruns, and in its expire() slot count the number of times it expired and implement switch or if-else logic to execute code once it's expired the proper number of times; resetting the counter after the largest tracked interval.

                          1 Reply Last reply
                          1
                          • A Anonymous_Banned275

                            I am back...
                            Single delay works as advertised...

                            I need ONE more advise ... how do I cascade / loop the delays ?
                            In another words - how start another single shot?
                            Obviously my code is again sequential , hence wrong.
                            Eventually I will need delays in a loop - sending asynchronous data...

                            if(1)
                            {
                            //startHelloWave();
                            startHelloWave(); // display starting time
                            // return;

                               // QTimer::singleShot(5*1000, this, SLOT(quit()));
                                ui->plainTextEdit_4->appendPlainText("Initial test delay ");
                                ui->plainTextEdit_4->appendPlainText("test delay ");
                            
                               startHelloWave();     // another delay
                            
                                ui->plainTextEdit_4->appendPlainText("AFTER delay test delay ");
                                ui->plainTextEdit_4->appendPlainText("test delay ");
                            
                            }
                            return;
                            
                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #12

                            @AnneRanch
                            The caller can set off multiple QTimer::singleshot()s (it's static) with different delays in advance, calling the same or different slots:

                            QTimer::singleShot(5 * 1000, this, &CCC_DiscoverDevice::helloWave);
                            QTimer::singleShot(10 * 1000, this, &CCC_DiscoverDevice::helloWave);
                            QTimer::singleShot(15 * 1000, this, &CCC_DiscoverDevice::differentWave);
                            

                            Or, the slot can set off a new one, calling the same or different slot:

                            void CCC_DiscoverDevice::helloWave()
                            {
                                ui->plainTextEdit_4->setPlainText(...);
                                QTimer::singleShot(15 * 1000, this, &CCC_DiscoverDevice::differentWave);
                                // if you call the same slot like next line, it will keep repeating, as this line will be hit again next time
                                // you'll need some `if (...)` if you no longer wish to keep repeating
                                QTimer::singleShot(15 * 1000, this, &CCC_DiscoverDevice::helloWave);
                            }
                            

                            Or, don't use singleShot(). QTimer is a repeating timer:

                            timerDelay->callOnTimeout(&CCC_DiscoverDevice::helloWave);
                            timer->start(5000);
                            

                            calls the same slot every 5 seconds. Call timer->stop() to switch it off.

                            1 Reply Last reply
                            2

                            • Login

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