Laschet Jain
Laschet Jain

Reputation: 744

Thread called more times while trying to exit from a thread

I wrote a program which creates two threads, each of which calls a function which basically prints and then call exit().

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>

void *myfunc(void* myvar)
{
    printf("Hello SO\n");
    exit(1);
    return NULL;
}

int main()
{
    pthread_t thread1 , thread2;
    char *msg1 = "First Thread";
    char *msg2 = "Second Thread";
    int ret1, ret2;

    ret1 = pthread_create(&thread1, NULL, myfunc, (void*)msg1);
    ret2 = pthread_create(&thread2, NULL, myfunc, (void*)msg2);

    pthread_join(thread1, NULL);
    pthread_join(thread2,NULL);

    return 0;
}

I am getting the following sets of output:

Output 1 (Desirable):

Hello SO

Output 2 (Desirable):

Hello SO

Hello SO

Output 3 (Undesirable as thread calls the functions two times only):

Hello SO

Hello SO

Hello SO

Please help me with figuring out the solution to output-3. Note : Everything works fine if I remove the exit().

Upvotes: 0

Views: 98

Answers (1)

P.P
P.P

Reputation: 121427

This is likely due to a bug in the glibc implementation of exit() which is unexplained output -- more output than the number of threads. When the process exits by calling exit(), it has to flush all streams, including stdout, to write all unwritten output from buffer. So it's possible that there is a "more" than what you wanted in stdout's buffer.

stdout is usually line buffer when attached to a terminal device. So I suspect you either don't have \n in the printf or do some sort of output redrection (such as pipe/rediecting to a file).

IIRC, glibc implementers didn't fix it and as a fix, you can call setbuf(stdout, 0); at the start of main() in order to disable the buffering. You can also call pthread_exit() instead of calling exit(). Remember exit() terminates the whole process. Besides, exit() is not thread-safe. So you can only call it safely when you know there's no race condition. To terminate just the thread, call pthread_exit() or simply return from the thread function.

I'll link the glibc bug report when I find it.

Upvotes: 2

Related Questions