RESOLVED I am having some problems with synchronization.
Firstly, the purpose of the file is to create 10 threads, and print the odd numbered ids before the even numbered ids.
As far as I can tell, my pthread_cond_wait is creating a deadlock. I was able to resolve this deadlock by including the signal below in the threadFunction. If I do not include this, I am stuck in running the program after all the odd numbers thread ids have been printed.
perror("Unable to pthread_cond_broadcast");
exit(EXIT_FAILURE);
}
Updated Section - Solution
void *threadFunction(void *threadId) {
if ((long) threadId % 2 == 0 && remainingOddThreads > 0) {
pthread_mutex_lock(&lock);
if (pthread_cond_wait(&evenCanGo, &lock)) {
perror("Error setting a pthread_cond_wait:");
exit(EXIT_FAILURE);
}
printf("Hello from thread[%ld]!\n", (long) threadId);
pthread_mutex_unlock(&lock);
} else {
if (pthread_mutex_lock(&lock)) {
perror("Unable to lock mutex:");
exit(EXIT_FAILURE);
}
printf("Hello from thread[%ld]!\n", (long) threadId);
remainingOddThreads--;
if (pthread_mutex_unlock(&lock)) {
perror("Unable to unlock mutex:");
exit(EXIT_FAILURE);
}
}
if (remainingOddThreads == 0) {
pthread_mutex_lock(&lock);
if (pthread_cond_signal(&evenCanGo)) {
perror("Unable to pthread_cond_broadcast");
exit(EXIT_FAILURE);
}
pthread_mutex_unlock(&lock);
}
return NULL;
}
This is the OLD code file
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <errno.h>
#define NUMBER_OF_ODD_NUMBERS_FROM_ONE_TO_TEN 5;
#define NUMBER_OF_THREADS 10
int remainingOddThreads = NUMBER_OF_ODD_NUMBERS_FROM_ONE_TO_TEN
pthread_t threads[NUMBER_OF_THREADS];
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t evenCanGo = PTHREAD_COND_INITIALIZER;
void *threadFunction(void *threadId) {
if ((long) threadId % 2 == 0 && remainingOddThreads > 0) {
if (pthread_cond_wait(&evenCanGo, &lock)) {
perror("Error setting a pthread_cond_wait:");
exit(EXIT_FAILURE);
}
printf("Hello from thread[%ld]!\n", (long) threadId);
} else {
if (pthread_mutex_lock(&lock)) {
perror("Unable to lock mutex:");
exit(EXIT_FAILURE);
}
printf("Hello from thread[%ld]!\n", (long) threadId);
remainingOddThreads--;
if (pthread_mutex_unlock(&lock)) {
perror("Unable to unlock mutex:");
exit(EXIT_FAILURE);
}
}
if (pthread_cond_signal(&evenCanGo)) {
perror("Unable to pthread_cond_broadcast");
exit(EXIT_FAILURE);
}
return NULL;
}
void createThreads() {
for (long i = 1; i <= NUMBER_OF_THREADS; i++) {
int status = pthread_create(&threads[i - 1], NULL, threadFunction, (void *) i);
if (status) {
perror("Failed to create thread");
exit(EXIT_FAILURE);
}
}
}
void activateThreads() {
for (long i = 0; i < NUMBER_OF_THREADS; i++) {
int status = pthread_join(threads[i], NULL);
if (status > 0) {
perror("Unable to join thread");
exit(EXIT_FAILURE);
}
}
}
int main() {
createThreads();
activateThreads();
if (pthread_cond_destroy(&evenCanGo) != 0) {
perror("Unable to destroy pthread_cond_t object:");
exit(EXIT_FAILURE);
}
pthread_mutex_unlock(&lock);
if (pthread_mutex_destroy(&lock) != 0) {
perror("Unable to destroy pthread_mutex_t object:");
printf("%d", errno);
exit(EXIT_FAILURE);
}
return 0;
}