2.7 Semáforos
Supongamos que estamos en un sistema operativo en el cual existen diversos procesos que necesitan ser ejecutados (P0, P1... Pn-1) cada uno de estos procesos pueden llegar a ser procesos cooperativos, dependiendo de la aplicación que se está ejecutando. Cada uno de los procesos tiene un segmento de código llamado sección crítica, en la que el proceso podría estar modificando variables comunes en caso de que sean procesos cooperativos. Así mismo pueden estar actualizando una tabla y/o escribiendo en un archivo.
Una de las características principales y muy importantes del sistema es
que, cuando un proceso se está ejecutando en su sección crítica, ningún otro
proceso puede ejecutarse en su sección crítica. A esto se le conoce como Exclusión
Mutua.
El problema de la sección crítica consiste en diseñar un protocolo
que los procesos puedan usar para cooperar, es decir no existan
conflictos mientras están trabajando. Cada proceso debe solicitar permiso para
poder ingresar en su sección crítica, no tiene derecho ni la facultad de poder
ingresar a ella cuando lo desee. La sección de código que implementa ésta
solicita es la sección de ingreso. La sección crítica puede ir seguida de una
sección de egreso. El código que queda es la sección restante.
Una solución al problema de la sección crítica debe satisfacer los
tres requisitos:
Mutua Exclusión: Si
el proceso Hi se está ejecutando en su sección crítica,
ningún otro proceso puede estar ejecutando en su sección crítica.
Progreso: Si ningún proceso se está ejecutando en su
sección crítica y hay procesos que deseen ingresar en sus secciones críticas,
sólo aquellos que no se están ejecutando en su sección restante podrán
participar en la decisión de cuál proceso será el siguiente en ingresar en su
sección crítica y ésta selección
no podrá postergarse indefinidamente.
Espera Limitada: Hay un límite para el número de veces
que se permite a otros procesos ingresar en sus secciones críticas después de
que un proceso ha solicitado ingresar a su sección crítica y antes de que se
le otorgue la autorización para hacerlo. El siguiente esquema muestra cual es
la secuencia de las distintas
secciones a las que accede un proceso.
REQUISITOS
PARA EXCLUSIÓN MUTUA
1.
La
exclusión mutua debe reforzarse: solo se permite un proceso a la vez dentro de
su sección crítica, entre todos los procesos que tienen secciones críticas
para el mismo recurso u objeto compartido.
2.
Un
proceso que se detiene en su sección no crítica debe hacerlo sin interferir
con otros procesos.
3.
No
debe ser posible que un proceso que requiere acceso a una sección crítica se
retrase en forma indefinida; no pueden permitirse el interbloqueo o la inanición.
4.
Cuando
ningún proceso está en una sección crítica, a cualquier proceso que solicite
entrada a su sección crítica se le debe permitir entrar sin retraso.
5.
No
se suponen velocidades de proceso relativas o números de procesos.
Un proceso permanece dentro de su sección crítica sólo durante un tiempo finito.
Existen varias maneras de satisfacer los requisitos de exclusión mutua. Una es dejar la responsabilidad en los procesos que desean ejecutar en forma concurrente. Entonces, ya sean programas del sistema o de aplicaciones, se requeriría que los procesos se coordinaran uno con otro para imponer la exclusión mutua, sin soporte del lenguaje de programación o del sistema operativo. Es decir, se habla de los enfoques de software, donde estos se encuentran propensos a una sobrecarga y errores de procesamiento. Un segundo enfoque implica el uso de instrucciones de máquina de propósito especial. Estas tienen la ventaja de reducir la sobrecarga pero no son atractivas. Un tercer enfoque es proporcionar cierto nivel de soporte dentro del sistema operativo. De igual forma, varios lenguajes de programación proporcionan características para procesamiento concurrente, lo cual significa que el soporte lo proporciona el compilador.
SEMÁFOROS
El
primer avance notable al tratar con los problemas de procesos concurrentes vino
en 1965 con el tratado de Dijkstra sobre procesos secuenciales cooperativos.
Dijkstra se interesó en el diseño de un sistema operativo como un conjunto de
procesos secuenciales cooperativos y con el desarrollo de mecanismos confiables
y eficientes para soportar la cooperación. Estos mecanismos pueden usarlos con
facilidad los procesos de usuario si el procesador y el sistema operativo ponen
disponible el mecanismo.
El
principio fundamental es el siguiente: dos o más procesos pueden cooperar por
medio de señales simples, de manera que se puede obligar a un proceso a
detenerse en un lugar especificado hasta que reciba una señal específica.
Cualquier requisito de coordinación compleja pude satisfacerlo la estructura
apropiada de señales. Para señalizar se usan variables llamadas semáforos.
Para transmitir una señal mediante un semáforo s, un proceso
ejecuta la primitiva signal (s). Para recibir una señal mediante el semáforo
s, un proceso ejecuta la primitiva wait(s), si la señal
correspondiente no se transmite todavía, el proceso se suspende hasta que
ocurre la transmisión. Las primitivas wait y signal se consideran
atómicas; esto es, no pueden interrumpirse y cada rutina puede tratarse como un
paso indivisible.