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:
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.
There is no guarantee in POSIX that the
pthread_t
type returned bypthread_self()
is a numeric type that can be cast to anunsigned 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:
Then in your threads use:
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.