Cada proceso tiene un segmento de código, llamado sección crítica, en el cual el
proceso puede estar modificando variables comunes, actualizando una tabla, escribiendo en un archivo, etc. Cuando un proceso se ejecuta en su sección crítica, no se permite que ningún otro proceso se ejecute en su sección. De esta manera, la ejecución de las secciones críticas de los procesos es mutuamente excluyente en el tiempo. El problema de la sección crítica consiste en diseñar un protocolo que los procesos puedan usar para cooperar. Cada proceso debe solicitar permiso para entrar en su sección crítica; la sección de código que implanta esta solicitud es la sección de entrada. A la sección crítica puede seguir una sección de salida y el código que queda es la sección restante.
Una solución al problema de la sección crítica debe cumplir los tres requisitos siguientes:
Exclusión mutua: si un proceso se está ejecutando en su sección crítica,
entonces ningún otro proceso se puede estar ejecutando en la suya. Progreso: si ningún proceso se está ejecutando en su sección crítica y hay otros procesos que desean entrar en las suyas, entonces solo aquellos procesos que no se están ejecutando en su sección restante pueden participar en la decisión de cuál será el siguiente en entrar en la sección crítica, y esta decisión no puede postergarse indefinidamente. Espera limitada: debe haber un límite en el número de veces que se permite que los demás procesos entren en su sección crítica después de que un proceso haya efectuado una solicitud para entrar en la suya y antes de que se conceda esa solicitud. Solución de Peterson
El Algoritmo de Peterson, también conocido como solución de PETERSON, es un
algoritmo de programación concurrente para Exclusión Mutua, que permite a dos o más procesos o hilos de ejecución compartir un recurso sin conflictos, utilizando solo memoria compartida para la comunicación.
El algoritmo de Peterson fue una simplificación del Algoritmo de Dekker.
Peterson desarrollo el primer algoritmo en 1981 para dos procesos.
Algoritmo para 2 procesos
bandera [0] = false
bandera [1] = false turno // No es necesario asignar un turno p0: bandera [0] = true p1: bandera [1] = true turno = 1 turno = 0 while (bandera [1] && turno == 1); while( bandera[0] && turno == 0 ); {//no hace nada; espera.} {//no hace nada; espera.} // sección crítica // sección crítica
// fin de la sección crítica // fin de la sección crítica
bandera [0] = false bandera [1] = false
Algoritmo para N procesos
// Variables compartidas bandera: array[0..N-1] of -1..n-2; /* inicializada a –1 */ turno: array[0..N-2] of 0..n-1; /* inicializada a 0 */
// Protocolo para Pi ( i=0,...,N-1 )
j:0..N-2; /* variable local indicando la etapa */ for j = 0 to N-2 { bandera[i] = j; turno[j] = i; while [(∃ k ≠ i : bandera[k] ≥ j) ∧ (turno[j] == i)] do; } <sección crítica> bandera[i] = -1;