sharkcathedral
sharkcathedral

Reputation: 43

unpredictable C++ sleep/wait behavior

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;
}

Upvotes: 3

Views: 223

Answers (2)

rustyx
rustyx

Reputation: 85286

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.

Upvotes: 2

podx47
podx47

Reputation: 34

#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; 
}

Upvotes: 1

Related Questions