Bug Hunting Adventures #3: Silent Threads

‘select’ isn’t broken
— The Pragmatic Programmers

Many moons ago, when I tried to familiarize myself with POSIX threads, I wrote a simple test program that was based on a textbook example.

My program sported two threads, one printing ‘+’ characters, the other one printing ‘-‘ characters. Everything worked as expected: a mixed stream of ‘+’ and ‘-‘ characters was emitted to stdout.

But everything happened so fast! Literally thousands of characters were outputted at the blink of an eye, so I added a little extra code that made the threads sleep for a specified amount of time before printing the next character.

Alas, when I set the delay (SLEEP_SECS) to 1 second (or in fact any value different to zero) nothing was printed at all! It looked like the threads got locked up completely. I came up with the weirdest theories about what had happened, including a bug in the pthreads library and the implementation of ‘sleep’.

It wasn’t until the next morning that I realized my mistake. Once I again, I had blamed it on the good ones, when the real problem was blind stupidity.

What was my mistake?

Code
Solution

Comments (3)

  1. 21:49, 29-10-2014sam  / Reply

    standard out is buffered until it gets a newline

  2. 12:36, 05-11-2014Daniel  / Reply

    The problem is with printf buffering. The program actually works very well if you wait for it to finish, you will see the ouput (the system will flush the process’s buffers before exiting thus it will print everything that buffered in stdout)

    Why does printf not flush after the call? The stdout stream is buffered, so will only display what’s in the buffer after it reaches a newline (or when it’s told to).

    You have a few options to print immediately:

    – Print to stderr instead using fprintf:
    fprintf(stderr, “I will be printed immediately”);

    – Flush stdout whenever you need it to using fflush:
    printf(“Buffered, will be flushed”);
    fflush(stdout); // Will now print everything in the stdout buffer

    – You can also disable buffering on stdout by using setbuf :
    setbuf(stdout, NULL);

    Daniel.

  3. 09:49, 04-12-2014Christian Hujer  / Reply

    The same problem happens frequently in all languages in all streams. Whether C and stdout or Java and a Socket doesn’t matter. Data stays in the buffer until it’s flushed.

Leave a Reply