pthread: one printf statement get printed twice in child thread

Solution 1:

Threading generally occurs by time-division multiplexing. It is generally in-efficient for the processor to switch evenly between two threads, as this requires more effort and higher context switching. Typically what you'll find is a thread will execute several times before switching (as is the case with examples 3 and 4. The child thread executes more than once before it is finally terminated (because the main thread exited).

Example 2: I don't know why x is increased by the child thread while there is no output.

Consider this. Main thread executes. it calls the pthread and a new thread is created.The new child thread increments x. Before the child thread is able to complete the printf statement the main thread kicks in. All of a sudden it also increments x. The main thread is however also able to run the printf statement. Suddenly x is now equal to 3. The main thread now terminates (also causing the child 3 to exit). This is likely what happened in your case for example 2.

Examples 3 clearly shows that the variable x has been corrupted due to inefficient locking and stack data corruption!!

For more info on what a thread is.

Link 1 - Additional info about threading

Link 2 - Additional info about threading

Also what you'll find is that because you are using the global variable of x, access to this variable is shared amongst the threads. This is bad.. VERY VERY bad as threads accessing the same variable create race conditions and data corruption due to multiple read writes occurring on the same register for the variable x. It is for this reason that mutexes are used which essentially create a lock whilst variables are being updated to prevent multiple threads attempting to modify the same variable at the same time. Mutex locks will ensure that x is updated sequentially and not sporadically as in your case.

See this link for more about Pthreads in General and Mutex locking examples.
Pthreads and Mutex variables

Cheers,
Peter

Solution 2:

Hmm. your example uses the same "resources" from different threads. One resource is the variable x, the other one is the stdout-file. So you should use mutexes as shown down here. Also a pthread_join at the end waits for the other thread to finish its job. (Usually a good idea would also be to check the return-codes of all these pthread... calls)

#include <pthread.h>
#include <stdio.h>
int x = 1;
pthread_mutex_t mutex;

void *func(void *p)
{
    pthread_mutex_lock (&mutex);
    x = x + 1;
    printf("tid %ld: x is %d\n", pthread_self(), x);
    pthread_mutex_unlock (&mutex);
    return NULL;
}

int main(void)
{
    pthread_mutex_init(&mutex, 0);

    pthread_t tid;
    pthread_create(&tid, NULL, func, NULL);

    pthread_mutex_lock (&mutex);
    printf("main thread:  %ld\n", pthread_self());
    pthread_mutex_unlock (&mutex);

    func(NULL);
    pthread_join (tid, 0);
}

Solution 3:

It looks like the real answer is Michael Burr's comment which references this glibc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=14697

In summary, glibc does not handle the stdio buffers correctly during program exit.