skip to Main Content

I must be doing something stupid because I am getting the weirdest behavior from this simple sleep code. Originally I was using std::this_thread::sleep_for and got the same results but assumed it must have been some thread strangeness. However, I am getting the same seemingly out-of-order waiting with the code below. Same results with clang++ or g++. I am on Debian and compiling at the command line.

Expected behavior:
Shutting down in 3… [wait one second] 2… [wait one second] 1… [wait one second; program exit]

Actual behavior:
[3 second long wait] Shutting down in 3… 2… 1… [program exit]

#include<chrono>
#include<iostream>

void Sleep(int i) {
    auto start = std::chrono::high_resolution_clock::now();
    auto now = std::chrono::high_resolution_clock::now();
    while (std::chrono::duration_cast<std::chrono::seconds>(now-start).count() < i)
        now = std::chrono::high_resolution_clock::now();
}

void ShutdownCountdown(int i) {
    if (i <= 0) return;

    std::cout << "Shutting down in ";
    for (; i != 0; --i) {
        std::cout << i << "... ";
        Sleep(1);
    }
    std::cout << std::endl << std::endl;
}

int main (int argc, char *argv[]) {
    ShutdownCountdown(3);

    return 0;
}

2

Answers


  1. #include<chrono>
    #include<iostream>
    
    void Sleep(int i) {
    auto start = std::chrono::high_resolution_clock::now();
    auto now = std::chrono::high_resolution_clock::now();
    while (std::chrono::duration_cast<std::chrono::seconds>(now-start).count() < i)
        now = std::chrono::high_resolution_clock::now();
    }
    
    void ShutdownCountdown(int i) {
    if (i <= 0) return;
    
    std::cout << "Shutting down in "<<std::flush;
    for (; i != 0; --i) {
        std::cout << i << "... "<<std::flush;
        Sleep(1);
    }
    std::cout << std::endl << std::endl;
    }
    
    int main (int argc, char *argv[]) {
    ShutdownCountdown(3);
    
    return 0; 
    }
    
    Login or Signup to reply.
  2. Normally iostreams do not flush until a newline is encountered. Since you don’t output an EOL character, you need to explicitly flush to get the output printed:

            std::cout << i << "... " << std::flush;
    

    Unrelated, but note also the CPU getting a bit hot when you run your program. To save energy, consider changing the busy loop back to a real sleep:

        for (; i != 0; --i) {
            std::cout << i << "... " << std::flush;
            std::this_thread::sleep_for(1s);
        }
    

    The nifty “1s” syntax is possible with using namespace std::chrono_literals; at the beginning of the program.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search