Algoritmo de Peterson para evitar la condición de carrera entre hilos

Detalles:

Estoy implementando el algoritmo de Peterson (abajo) para evitar la condición de la raza. La forma en que quiero hacerlo es declarar una variable de entero global y crear subprocesos uno y dos. Siempre que el subproceso uno tenga acceso a la variable global, debe imprimir a y agregarla al contador de la variable global. Cuando el subproceso dos tenga acceso a esta variable global, debe imprimir b y agregar uno al contador de variables globales. Esto debería continuar hasta que la variable global scope un cierto número (digamos 10). Después de eso quiero que el hilo (cualquiera de los dos hilos que hace la última adición a la variable global) restablezca la variable global a 1 y que ambos hilos salgan. El código que he implementado hasta ahora hace un poco el trabajo, evita la condición de carrera, pero no puedo salir de ambos subprocesos cuando el contador llega al límite.

Pregunta:

  • ¿Cómo puedo salir de ambos hilos cuando el contador alcanza un límite específico?

  • ¿Cuál es la forma correcta de salir de un hilo? En este momento estoy usando exit (), que no creo que sea muy eficiente.

Algoritmo de Peterson

 boolean flag [2]; int turn; void P0() { while (true) { flag [0] = true; turn = 1; while (flag [1] && turn == 1) /* do nothing */; /* critical section */; flag [0] = false; /* remainder */; } } void P1() { while (true) { flag [1] = true; turn = 0; while (flag [0] && turn == 0) /* do nothing */; /* critical section */; flag [1] = false; /* remainder */ } } void main() { flag [0] = false; flag [1] = false; parbegin (P0, P1); } 

Mi código:

EDITAR : Me di cuenta de que tengo que poner la sentencia if, que es verificar el valor límite del contador, debería estar en la sección crítica (antes de que cambie el indicador a falso).

 #include #include #include int counter = 0; int flag[2]; int turn; void *func1(void *); void *func2(void *); int main(int argc,char *argv[]){ pthread_t thread1,thread2; //int rt1,rt2; flag[0] = 0; flag[1] = 0; //rt1 = pthread_create(&thread1,NULL,&func1,"a"); //rt2 = pthread_create(&thread2,NULL,&func2,"c"); pthread_create(&thread1,NULL,&func1,"a"); pthread_create(&thread2,NULL,&func2,"b"); pthread_join(thread1,NULL); pthread_join(thread2,NULL); return 0; }// End of main function void *func1(void *message){ while(1){ flag[0] = 1; turn = 1; while(flag[1] && turn == 1); printf("%s %d\n",(char *)message,counter); counter++; flag[0] = 0; if(counter == 10){ counter = 1; printf("exited at func1, with counter %d\n",counter); exit(0); } } return 0; } void *func2(void *message){ while(1){ flag[1] = 1; turn = 0; while(flag[0] && turn == 0); printf("%s %d\n",(char *)message,counter); counter++; flag[1] = 0; if(counter == 10){ counter = 1; printf("exited at func2, with counter %d\n",counter); exit(0); } } return 0; } 

Obviamente, cuando un hilo restablece el contador global, es posible que el otro hilo nunca vea que el contador global llegue a eg10, por lo que nunca se cerrará. ¿Qué sucede si simplemente no restablece el contador global y deja que se salga de la secuencia cada vez que encuentra el contador global, por ejemplo, 10? Si realmente desea restablecer el contador, hágalo en el hilo principal (principal) (que también es donde se define el contador global).

En cuanto a salir de un hilo, puede regresar desde la función del hilo principal (esto terminará el hilo por sí mismo), llamar a pthread_exit desde el hilo, o puede usar phtread_cancel desde la función principal.