sapy
sapy

Reputation: 9582

cout not printing string and variable value consistently , misaligning the output

In the following code threadCount is one of 1,2,3,4 . But in the output, though the string part getting printed perfectly the num value getting missed randomly and it's getting appended after a few lines at times.

void *SPWork(void *t)
{

    int* threadC = (int*)t;
    int threadCount = *threadC;
    cout<<"\n Thread count" << threadCount << endl;
    cout << flush;
    long long int i, adjustedIterationCount;
    adjustedIterationCount = 100/(threadCount);
    for (i=0; i< adjustedIterationCount; i++)
    {
        i++ ;
    }
    pthread_exit((void*) t);
}

Output

......
.....
Thread count1
 Thread count1
 Thread count2
 Thread count1
 Thread count
 Thread count
 Thread count234
 .....
 .....

Notice in the last line thread value is 234. But that value will never be 234.In the previous 2 line that value didn't get appended and so 2,3 got added to this line.

I know it got to do with flush or appending "\n", tried many combinations. But still, the issue persists.

N.B. This is a worker method of a pthread, compiler flags are "-g -Wall -O3 -lpthread"

Upvotes: 0

Views: 605

Answers (2)

paxdiablo
paxdiablo

Reputation: 881273

There is no requirement that your calls to cout are an atomic operation. If you need them to be so, you can simply protect the code (just the output code) with a mutex.

In addition, injecting std::endl into the stream already flushes the data so there's little point in following that with a std::flush.

So, in its simplest form:

pthread_mutex_lock(&myMutex);
std::cout << "\n Thread count" << threadCount << std::endl;
pthread_mutex_unlock(&myMutex);

Note that, for recent C++ implementations, it's probably better to use std::mutex and std::lock_guard since they can guarantee correct clean up (see other answers for this). Since you have pthread_exit() in your code, I assume your limited to the POSIX threading model.

Upvotes: 1

Miles Budnek
Miles Budnek

Reputation: 30494

While the standard streams are guaranteed to be thread-safe, there is no guarantee that the output won't be interleaved. If you want to print to a standard stream from multiple threads in a predictable way, you will need to do some synchronization yourself:

std::mutex cout_mutex;

void *SPWork(void *t)
{
    //...
    {
        std::lock_guard<std::mutex> guard(cout_mutex);
        std::cout << "\n Thread count" << threadCount << std::endl;
    }
    //...
}

Upvotes: 2

Related Questions