Create multiple threads from a single thread variable

ghz 8months ago ⋅ 144 views

I've been learning about threads lately and I'm confused about something. I thought we can only create one thread from a thread variable and that thread can only execute one job, but in the code below, I create four threads from a global thread variable and they print at the same time. What I mean by 'at the same time' is that all functions run without waiting for the previous one to complete.

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

pthread_t thread;

void *func4() {

    int i;

    for(i = 0; i < 5; i++){

        printf("/\n");
        sleep(1);
    }
}

void *func3() {

    pthread_create(&thread, NULL, func4, NULL);

    int i;

    for(i = 0; i < 5; i++){

        printf("*\n");
        sleep(1);
    }

    pthread_join(thread, NULL);
}

void *func2() {

    pthread_create(&thread, NULL, func3, NULL);

    int i;

    for(i = 0; i < 5; i++){

        printf("-\n");
        sleep(1);
    }

    pthread_join(thread, NULL);
}

void *func1() {

    pthread_create(&thread, NULL, func2, NULL);

    int i;

    for(i = 0; i < 5; i++){

        printf("+\n");
        sleep(1);
    }

    pthread_join(thread, NULL);
}

int main() {

    pthread_create(&thread, NULL, func1, NULL);
    pthread_join(thread, NULL);

    return 0;
}

Is this a concept or do I know or use something wrong?

Answers

What you're observing is a common misconception about threads. Each call to pthread_create creates a new thread of execution, which means that your code spawns multiple threads that run concurrently. However, the way you're using pthread_join inside each function effectively makes the main thread wait for the spawned thread to complete before continuing execution.

Let's break down your code:

  1. In the main function, you create a thread running func1 using pthread_create and then immediately wait for it to finish using pthread_join. This means the main thread will wait for func1 to finish before continuing.
  2. Inside func1, you create a new thread running func2, but before doing so, you wait for the thread started by func2 to finish using pthread_join. So effectively, func1 waits for func2 to finish before continuing.
  3. This pattern continues, so func2 waits for func3, and func3 waits for func4.
  4. Each function prints its own character (+, -, *, /) and sleeps for 1 second between prints.

So, while it might seem like all the threads are printing simultaneously, they are actually printing sequentially due to the way you've structured your code with pthread_join.

If you removed the pthread_join calls from each function, you would indeed see the threads printing their characters concurrently, potentially interleaving the output chaotically. But keep in mind that without synchronization mechanisms like mutexes or semaphores, concurrent access to shared resources (like the terminal in this case) can lead to unexpected results.