I was trying to learn something about parallel programming, so I tried to implement the Peterson algorithm for a simple example, when one common counter is incremented by 2 threads. I know that Peterson is not optimal due to lively expectations, but I tried it only for study reasons.
I suggested that the critical part of this code is in the add
thread function, where the total counter
incremented. Therefore, I call the enter_section
function before the increment of the counter, after which I call leave_function
. Is this part wrong? Am I really mistaken in the critical section? The problem is that the counter sometimes gives an undefined value when these 2 threads are executed. It should be a synchronization problem between threads, but I just don't see it ... Thanks for any help.
#include <stdio.h> #include <stdlib.h> #include <pthread.h> int counter; /* global shared counter */ int flag[2] = {0, 0}; /* Variables for Peterson algorithm */ int turn = 0; typedef struct threadArgs { pthread_t thr_ID; int num_of_repeats; int id; } THREADARGS; void enter_section (int thread) { int other = 1 - thread; flag[thread] = 1; turn = thread; while ((turn == thread) && (flag[other] == 1)); return; } void leave_section (int thread) { flag[thread] = 0; return; } void * add (void * arg) { int i; THREADARGS * a = (THREADARGS *) arg; for (i = 0; i < a->num_of_repeats; i++) { enter_section(a->id); counter++; leave_section(a->id); } return NULL; } int main () { int i = 1; pthread_attr_t thrAttr; THREADARGS threadargs_array[2]; pthread_attr_init (&thrAttr); pthread_attr_setdetachstate (&thrAttr, PTHREAD_CREATE_JOINABLE); /* creating 1st thread */ threadargs_array[0].id = 0; threadargs_array[0].num_of_repeats = 1000000; pthread_create(&threadargs_array[0].thr_ID, &thrAttr, add, &threadargs_array[0]); /* creating 2nd thread */ threadargs_array[1].id = 1; threadargs_array[1].num_of_repeats = 2000000; pthread_create(&threadargs_array[1].thr_ID, &thrAttr, add, &threadargs_array[1]); /* free resources for thread attributes */ pthread_attr_destroy (&thrAttr); /* waiting for 1st thread */ pthread_join (threadargs_array[0].thr_ID, NULL); printf("First thread is done.\n"); /* waiting for 2nd thread */ pthread_join (threadargs_array[1].thr_ID, NULL); printf("Second thread is done.\n"); printf("Counter value is: %d \n", counter); return (EXIT_SUCCESS); }
source share