Following is a program which uses pthreads.
#include <pthread.h> // posix threads
#include <stdio.h>
#include <stdlib.h>
/* to compile use -lpthread */
void * sample_thread(void *);
#define MAX 10
int main()
{
pthread_t tid;
pthread_attr_t attr;
int k;
pthread_attr_init(&attr); // set default attributes
pthread_create(&tid, &attr, sample_thread, NULL); // create new thread
// sample_thread will run as the new thread
for(k=0; k<MAX; k++) {
printf("Hi I'am %s %d \n",__func__,k);
}
//this would kill all the threads,
}
void * sample_thread(void * p)
{
int k;
for(k=0; k<MAX; k++) {
printf("Hi I'am %s %d \n",__func__,k);
}
}
Each time when I run the program I am expecting to get different number of execution numbers from the main thread and the child thread (because the main thread might exit before the child). I am getting this expected output sometimes. But I got an output as follows, which I am unable to understand why.
Hi I'am main 0
Hi I'am main 1
Hi I'am main 2
Hi I'am main 3
Hi I'am main 4
Hi I'am main 5
Hi I'am main 6
Hi I'am main 7
Hi I'am main 8
Hi I'am main 9
Hi I'am sample_thread 0
Hi I'am sample_thread 0
Hi I'am sample_thread 1
Hi I'am sample_thread 2
Hi I'am sample_thread 3
Hi I'am sample_thread 4
Hi I'am sample_thread 4
Hi I'am sample_thread 5
Why did the sample thread 0 and 4 print twice?
As highlighted by @R.. in the comments, this appears to be a bug in the implementation of glibc (assuming you are using Linux -- I can reproduce this on Linux 2.17 compiled with GCC 4.9.1), in that
exit()
doesn't ensure, while flushing and closing streams, there's no race when it's called by one thread when multiple threads use stdout.The following from
flockfile
manual clearly indicates that the behaviour observed is not correct:In light of this, the following options can be considered as a workaround (as there's no response to the bug report) to this particular case that we observed here.
Both the threads "share" the
stdout
stream and I think, the "extra" output is printed because of the premature exit of main thread.printf
buffers (insample_thread()
) the output and before it could clear it's buffer (due to\n
in printfs), main thread exits. Hence forcing the flush ofstdout
buffer when the process exits.To fix,
1) you could call
setbuf()
inmain()
before creating the thread:to not buffer
stdout
at all.Or
2) call
pthread_exit()
in both threads so that the process continues if either thread dies.Or
3) call
pthread_join()
in main thread so that main thread waits for the completion ofsample_thread
thread.Either one of these will avoid the issue.