Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BOOST threading : cout behavior

I am new to Boost threading and I am stuck with how output is performed from multiple threads. I have a simple boost::thread counting down from 9 to 1; the main thread waits and then prints "LiftOff..!!"

#include <iostream>
#include <boost/thread.hpp>
using namespace std;

struct callable {
    void operator() ();
};

void callable::operator() () {
    int i = 10;
    while(--i > 0) {
        cout << "#" << i << ", ";
        boost::this_thread::yield();
    }
    cout.flush();
}

int main() {
    callable x;
    boost::thread myThread(x);

    myThread.join();

    cout << "LiftOff..!!" << endl;

    return 0;
}

The problem is that I have to use an explicit "cout.flush()" statement in my thread to display the output. If I don't use flush(), I only get "LiftOff!!" as the output.

Could someone please advise why I need to use flush() explicitly?

like image 230
Rajat Avatar asked May 28 '12 12:05

Rajat


2 Answers

This isn't specifically thread related as cout will buffer usually on a per thread basis and only output when the implementation decides to - so in the thread the output will only appear on a implementation specific basic - by calling flush you are forcing the buffers to be flushed.

This will vary across implementations - usually though it's after a certain amount of characters or when a new line is sent.

I've found that multiple threads writing too the same stream or file is mostly OK - providing that the output is performed as atomically as possible. It's not something that I'd recommend in a production environment though as it is too unpredictable.

like image 186
Richard Harrison Avatar answered Nov 06 '22 04:11

Richard Harrison


This behaviour seems to depend on OS specific implementation of the cout stream. I guess that write operations on cout are buffered to some thread specific memory intermediatly in your case, and the flush() operation forces them being printed on the console. I guess this, since endl includes calling the flush() operation and the endl in your main function doesn't see your changes even after the thread has been joined.

BTW it would be a good idea to synchronize outputs to an ostream shared between threads anyway, otherwise you might see them intermigled. We do so for our logging classes which use a background thread to write the logging messages to the associated ostream.

like image 33
πάντα ῥεῖ Avatar answered Nov 06 '22 03:11

πάντα ῥεῖ