Skip to content
Home » How to use the pthread_join Function in C

How to use the pthread_join Function in C

Learn about C Program to use the pthread_join Function in the below code example. Also refer the comments in the code snippet to get a detailed view about what’s actually happening.

C program to use pthread_join function to wait for thread termination:

Threads are created by a program using the pthread create function, and they are normally terminated using the pthread join function. pthread join accepts only two arguments: a thread id to define the waited thread and a reference to void* where the specified thread’s exit status can be kept. If the user does not want to receive the exit code of the waited thread, the second argument should be NULL.

The software in the following example generates eight threads and executes the printHello function in each of them. The calling thread then waits in the loop for every thread that has used the pthread join function. It’s worth noting that we also save and report the threads’ exit status codes in the retval variable.

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

#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif

void *printHello(void *threadid) {
    long tid;
    tid = (long)threadid;
    printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
    return NULL;
}


int main(int argc, char const *argv[]) {
    pthread_t threads[NUM_THREADS];
    int rc;
    long t;

    for (t = 0; t < NUM_THREADS; t++) {
        rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
        if (rc) {
            printf("ERORR; return code from pthread_create() is %d\n", rc);
            exit(EXIT_FAILURE);
        }
    }

    int ret;
    for (t = 0; t < NUM_THREADS; t++) {
        void *retval;
        ret = pthread_join(threads[t], &retval);
        if (retval == PTHREAD_CANCELED)
            printf("The thread was canceled - ");
        else
            printf("Returned value %d - ", (int)retval);
    }
    pthread_exit(NULL);
}

Output:

Hello from thread 1, pthread ID – 2
Hello from thread 0, pthread ID – 1
Hello from thread 2, pthread ID – 3
Hello from thread 3, pthread ID – 4
Hello from thread 5, pthread ID – 6
Hello from thread 6, pthread ID – 7
Hello from thread 4, pthread ID – 5
Hello from thread 7, pthread ID – 8

C program to use pthread_join function to return value to check errors:

The pthread_join function returns an integer value that also indicates different error codes in contrast to a function that sets an errno global variable. The return value is 0 if the call was successful and this guarantees the given thread has terminated. If the returned integer is equal to EDEADLK, it reports that a deadlock was detected. If EINVAL value is returned, then the given thread is not joinable, and if the value equals ESRCH, it indicates that the given thread ID can’t be found. In this case, we implement a switch statement to check for each case and print the corresponding message to stdout.

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

#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif

void *printHello(void *threadid) {
    long tid;
    tid = (long)threadid;
    printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
    return NULL;
}

int main(int argc, char const *argv[]) {
    pthread_t threads[NUM_THREADS];
    int rc;
    long t;

    for (t = 0; t < NUM_THREADS; t++) {
        rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
        if (rc) {
            printf("ERORR; return code from pthread_create() is %d\n", rc);
            exit(EXIT_FAILURE);
        }
    }

    int ret;
    for (t = 0; t < NUM_THREADS; t++) {
        void *retval;
        ret = pthread_join(threads[t], &retval);
        if (retval == PTHREAD_CANCELED)
            printf("The thread was canceled - ");
        else
            printf("Returned value %d - ", (int)retval);


        switch (ret) {
            case 0:
                printf("The thread joined successfully\n");
                break;
            case EDEADLK:
                printf("Deadlock detected\n");
                break;
            case EINVAL:
                printf("The thread is not joinable\n");
                break;
            case ESRCH:
                printf("No thread with given ID is found\n");
                break;
            default:
                printf("Error occurred when joining the thread\n");
        }
    }
    pthread_exit(NULL);
}

Output:

Hello from thread 0, pthread ID – 1
Hello from thread 1, pthread ID – 2
Hello from thread 4, pthread ID – 5
Hello from thread 3, pthread ID – 4
Hello from thread 5, pthread ID – 6
Hello from thread 2, pthread ID – 3
Hello from thread 6, pthread ID – 7
Hello from thread 7, pthread ID – 8
Returned value 0 – The thread joined successfully
Returned value 0 – The thread joined successfully
Returned value 0 – The thread joined successfully
Returned value 0 – The thread joined successfully
Returned value 0 – The thread joined successfully
Returned value 0 – The thread joined successfully
Returned value 0 – The thread joined successfully
Returned value 0 – The thread joined successfully

Hope above code works for you and Refer the below Related Codes to gain more insights. Happy coding and come back again.

Also Read:
How to Write C++ Program Without Header File using extern
How to Write C Program Without Header File

Tags: