Multithreaded program not producing desired output

87 views Asked by At

I am writing a code that creates 10 threads and executes those threads with even thread ids first and then executes all those with odd thread ids next. I'm using the POSIX threads library. Here is the code I wrote:

#include "stdlib.h"
#include "pthread.h"
#include "stdio.h"

#define TRUE 1
#define FALSE 0

int EVEN_DONE = FALSE;
int evenThreads, oddThreads = 0;
int currentThread = 0;

//the mutex for thread synchronization
static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;

//the condition variable;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;



void * printEven(unsigned long id)
{
    pthread_mutex_lock(&mymutex);
        evenThreads++;
        printf("TID: %lu, Hello from even\n", id);
        // this condition checks whether even threads have finished executing
        if(evenThreads + oddThreads >= 10) {
            EVEN_DONE = TRUE;
            pthread_cond_broadcast(&cond);
        }
    pthread_mutex_unlock(&mymutex);
    return NULL;
}

void * printOdd(unsigned long id)
{
    pthread_mutex_lock(&mymutex);

    while (!EVEN_DONE) {
        oddThreads++;
        pthread_cond_wait(&cond, &mymutex);
        printf("TID: %lu, Hello from odd\n", id);
    }
    pthread_mutex_unlock(&mymutex);
    return NULL;
}



void * threadFunc(void *arg)
{
    unsigned long id = (unsigned long)pthread_self();
    if (id % 2 == 0)
    {
        printEven(id);

    }

    else
    {
        printOdd(id);
    }

    return NULL;
}

int main()
{
    pthread_t* threads;
    int num_threads = 10;

    int i, j;

    threads = malloc(num_threads * sizeof(threads));
    for ( i = 0; i < 10; i++) {
        pthread_create(&threads[i], NULL, threadFunc, NULL);
    }
    for ( j = 0; j < 10; j++) {

        pthread_join(threads[j], NULL);
    }

   printf("Finished executing all threads\n");

    return 0;
}

However, when I run the code it doesn't produce the desired output. The output I'm getting is this:

output image

Apparently, it seems that all the thread IDs are even numbers. However, I do think there is a problem with my code. What am I doing wrong? How can I achieve the desired output?

(Note: I'm at beginner level when it comes to POSIX threads and multithreading in general)

Thanks in advance.

1

There are 1 answers

0
caf On BEST ANSWER

There is no guarantee in POSIX that the pthread_t type returned by pthread_self() is a numeric type that can be cast to an unsigned long - it is allowed to be a structure type, for example.

If you want to write your code in a POSIX-conforming way, you will need to allocate numeric thread IDs yourself. For example, you could have:

unsigned long allocate_id(void)
{
    static unsigned long next_id = 0;
    static pthread_mutex_t id_lock = PTHREAD_MUTEX_INITIALIZER;
    unsigned long id;

    pthread_mutex_lock(&id_lock);
    id = next_id++;
    pthread_mutex_unlock(&id_lock);
    return id;
}

Then in your threads use:

unsigned long id = allocate_id();

Controlling the allocation of IDs yourself also allows you to control the sequence - for example in this case you can ensure that IDs are sequentially allocated so that you will have both odd and even IDs.