Home > Mobile >  Behaviour of simple multithread program on C
Behaviour of simple multithread program on C

Time:08-13

I'm training on C and threads. I found the following code from this page and compiled it on my Ubuntu 20.04 machine:

// C program to show thread functions

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

void* func(void* arg)
{
    // detach the current thread
    // from the calling thread
    pthread_detach(pthread_self());

    usleep(3*1000000);
    printf("Inside the thread\n");

    // exit the current thread
    pthread_exit(NULL);
}

void fun()
{
    pthread_t ptid;

    // Creating a new thread
    pthread_create(&ptid, NULL, &func, NULL);
    printf("This line may be printed"
        " before thread terminates\n");

    // The following line terminates
    // the thread manually
    // pthread_cancel(ptid);

    // Compare the two threads created
    if(pthread_equal(ptid, pthread_self()))
        printf("Threads are equal\n");
    else
        printf("Threads are not equal\n");

    // Waiting for the created thread to terminate
    pthread_join(ptid, NULL);

    printf("This line will be printed"
        " after thread ends\n");

    pthread_exit(NULL);
}

// Driver code
int main()
{
    fun();
    return 0;
}

I just added a usleep in the thread function but the behavior doesn't change. If I understand everything correctly the message "This line will be printed after thread ends" shall be always printed at the very end of the program, when thread ptid is ended.

But in reality, it often happens that this ending message is printed and then after 3 seconds (due to usleep call) it is printed the message "Inside the thread", seeming that thread ptid is still alive and running.

Without the usleep (as per original code) happened the same just without the 3s wait in the middle.

What's going wrong?

CodePudding user response:

A spotted in the comments, the source of the main issue of your code is that you call pthread_detach.

The later pthread_join will just ignore the thread you detach.

At this point all thread "live their own life" which means the the only remaining synchronization mechanism is at the "exit" (when main returns). On exit, the compiler added some code that will wait for all threads to terminate.

So as threads are not synchronized in any way, what is happening is just a race condition.

When adding the usleep, you just delay the fist thread enough for the other one to have much time to finish first.

When no usleep, the race just produces random order of logs.

Worth to notice that stdout is bufferized, so the output may not be displayed at the time the printf call is done.

Remove the pthread_detach() will restore the synchro provided by pthread_join, so the log will appea in the order you expect (if I put aside the stdout bufferization pb)

  • Related