I am supposed to reproduce the Strict Alternation algorithm using C and Posix Threads.
I coded the below solution but the printfs aren't being outputed at all. Sometimes just the my_id is outputed but that's all. What am I doing or understanding wrong?
For example, this was the output of one of the times I ran this code:
Here is the code I did:
#include <pthread.h>
#include <stdio.h>
int count = 0;
int turn = 1;
struct arg_struct {
int my_id;
int other;
};
void *runner(void *param) {
struct arg_struct *args = (struct arg_struct *)param;
int my_id = args -> my_id;
int other = args -> other;
printf("my_id %d\n", my_id);
printf("other %d\n", other);
printf("Running p_thread %d\n", my_id);
while(1) {
while (turn != my_id) { }
// critical section
count = count my_id;
printf("Critical section of p_thread %d, count was incremented by %d and is now %d\n", my_id, my_id, count);
turn = other;
// not critical section
printf("Not critical section of p_thread %d\n", my_id);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int thr_id1, thr_id2;
pthread_t p_thread1;
pthread_t p_thread2;
struct arg_struct args_p_thread1;
args_p_thread1.my_id = 1;
args_p_thread1.other = 2;
struct arg_struct args_p_thread2;
args_p_thread2.my_id = 2;
args_p_thread2.other = 1;
thr_id1 = pthread_create(&p_thread1, NULL, runner, (void*)&args_p_thread1);
thr_id2 = pthread_create(&p_thread2, NULL, runner, (void*)&args_p_thread2);
return 0;
}
CodePudding user response:
The variable you use for your parameters is reused between the threads.
Your global variables are not immediately suitable for sharing between threads, so it’s possible they do not see a new value of turn and get stuck in your inner while loop.
Your main loop exits without waiting for the threads, so they may not get a chance to do much. Your program will exit at the end of the main thread, it will not automatically wait for your other threads.
CodePudding user response:
This code works for me on Repl.it.
I added volatile and pthread_join
#include <pthread.h>
#include <stdio.h>
int count = 0;
volatile int turn = 1;
struct arg_struct {
int my_id;
int other;
};
void *runner(void *param) {
struct arg_struct *args = (struct arg_struct *)param;
int my_id = args -> my_id;
int other = args -> other;
printf("my_id %d\n", my_id);
printf("other %d\n", other);
printf("Running p_thread %d\n", my_id);
while(1) {
while (turn != my_id) { }
// critical section
count = count my_id;
printf("Critical section of p_thread %d, count was incremented by %d and is now %d\n", my_id, my_id, count);
turn = other;
// not critical section
printf("Not critical section of p_thread %d\n", my_id);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int thr_id1, thr_id2;
pthread_t p_thread1;
pthread_t p_thread2;
struct arg_struct args_p_thread1;
args_p_thread1.my_id = 1;
args_p_thread1.other = 2;
struct arg_struct args_p_thread2;
args_p_thread2.my_id = 2;
args_p_thread2.other = 1;
thr_id1 = pthread_create(&p_thread1, NULL, runner, (void*)&args_p_thread1);
thr_id2 = pthread_create(&p_thread2, NULL, runner, (void*)&args_p_thread2);
int join = 0;
pthread_join(&p_thread1, &join);
pthread_join(&p_thread2, &join);
return 0;
}