4

I'm trying out a simple program to test multi-threading. I just print a series of "x" and "O" in alternate threads. Now, if I use cout , no output is seen on screen. If I use fputc and output to stderr , it works fine. Why is cout (output to stdout) not working here ?

My code is given below :

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

using namespace std;

static int count;

void* print_xs(void *unused)
{
    while(1)
    {
        if (count >=100) break;
        if (count%2==0)
        {
            count++;
            cout<<"X=";  // no output here
            fputc('X',stderr); // works !
        }
        else
        {
            sleep(1);
        }
    }
    return NULL;

}


int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,&print_xs, NULL);

    while(1)
    {
        if (count >=100) break;
        if (count%2!=0)
        {
            count++;
            cout<<"O="; // no output here 
            fputc('O',stderr); // works !
        }
        else
        {
            sleep(1);
        }
    }

    pthread_join(tid,NULL);
    return (0);

}
vinit
  • 501
  • 5
  • 15

1 Answers1

1

Since std::cout is a buffered-stream, you need to flush it in order to send the buffer to the standard output.

Just try something like:

cout<< "O=";
cout.flush();

That should work.

Additional notes

  1. As some comments have already suggest you, std::cout is not thread-safe in C++03 and before. It could be useful to protect that object with a mutex. This could be not a problem since C++11 standard.

The FDIS says the following in §27.4.1 [iostream.objects.overview]:

Concurrent access to a synchronized (§27.5.3.4) standard iostream object’s formatted and unformatted input (§27.7.2.1) and output (§27.7.3.1) functions or a standard C stream by multiple threads shall not result in a data race (§1.10). [ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. — end note ]

That means without mutex it's guaranteed the object will not corrupted in a data-race context. But the problem on overlapped output remains. So if you be sure each line is printed without overlap by another thread, you still need a mutex.

  1. C++11 has introduces a multi-thread library (often is a wrapper for pthread). Here some reference. Just take a look at, you could find it useful.
Community
  • 1
  • 1
BiagioF
  • 9,368
  • 2
  • 26
  • 50
  • Thanks, but I did not understand why this is a problem only when using threads ? When I use cout normally, it correctly displays on stdout. – vinit Aug 22 '16 at 10:50
  • That's no true. Even in a single-thread you got that behaviour. I think you've never noticed that. I've just written a simple code which print 10 times a string (*without `\n`*): `for(...) std::cout << "something";` and following with a debugger nothing is written until the end of the program. (You can try also, but that depend on the particular implementation). If you need, I can also modify my answer and show you that behaviour. – BiagioF Aug 22 '16 at 12:16
  • @vinit I forgot to tag you :) – BiagioF Aug 22 '16 at 12:37
  • I see , so cout just keeps buffering until it encounters a '\n' or its flushed out ? Thanks, I did not know this .... there's always something new to learn in C++ :) – vinit Aug 23 '16 at 08:46
  • 1
    @vinit Actually there is no guarantee the stream is flushed when `'\n'` is encounter. That why `std::endl` which inserts the new line character `'\n'` and flush the stream. If you want you can mark the answer as correct. – BiagioF Aug 23 '16 at 08:58