Este documento describe conceptos clave de la programación concurrente como multitarea, multiprogramación y multiprocesos. Explica que la programación concurrente permite ejecutar múltiples tareas de forma simultánea a través de procesos o hilos. También cubre temas como la comunicación y sincronización entre procesos, algoritmos para exclusión mutua como Dekker y Peterson, y herramientas para la sincronización como semáforos y monitores.
2. PROGRAMACIÓN CONCURRENTE*
La programación concurrente es la simultaneidad en la ejecución de
múltiples tareas interactivas. Estas tareas pueden ser un conjunto de
procesos o hilos de ejecución creados por un único programa. Las tareas se
pueden ejecutar en un sola CPU (multiprogramación), en varios
procesadores o en una red de computadores distribuidos.
La programación concurrente está relacionada con la programación
paralela, pero enfatiza más la interacción entre tareas. Así, la correcta
secuencia de interacciones o comunicaciones entre los procesos y el acceso
coordinado de recursos que se comparten por todos los procesos o tareas son
las claves de esta temática.
* Circunstancia de suceder o producirse varias cosas en un mismo momento
3. Multitarea, Multiprogramación, Multiprocesos
La programación concurrente tiene capacidad para realizar varias tareas al
mismo tiempo o muchas tareas en una sola PC con un procesador o varios.
4. Multitareas
Es la capacidad de un sistema operativo para ejecutar varios procesos al
mismo tiempo corriendo sobre un procesador.
Con los sistemas operativos DOS esto era incapaz de realizarse.
Existen varios tipos de multitareas y son :
Multitarea Nula
Multitarea Cooperativa
Multitarea Preferente
Multitarea Real
5. Multitarea Nula
Es aquel sistema operativo que
carece de multitarea. Aún así puede
simularla implementándola en un
espacio de usuario o usando trucos
como los TSR (terminate and stay
resident. programa que se encuentra
en la memoria del ordenador y que
se puede activar accionando una
secuencia especial de teclas) en MS-
DOS. Justamente la familia DOS son
ejemplos de sistemas operativos de
multitarea nula.
6. Multitarea Cooperativa
Tipo de multitarea en donde los
procesos de usuario son quienes ceden
la CPU al sistema operativo a intervalos
regulares.
Es sumamente problemático porque si
por algún motivo el proceso de usuario
es interrumpido, no cede la CPU al
sistema operativo que lo ejecuta y, por
lo tanto, quedará bloqueado.
Los sistemas operativos Windows antes
de la versión 1995 implementaban este
tipo de multitarea.
7. Multitarea Preferente
Multitarea en donde el SO se encarga de administrar uno o más
procesadores, repartiendo el tiempo de uso del mismo entre los distintos
procesos que esperan utilizarlo (tareas en ejecución).
En el caso de un solo procesador, cada proceso o tarea lo utiliza en períodos
cortísimos de tiempo, lo que, en la práctica, da la sensación de que
estuviesen ejecutándose al mismo tiempo. Los sistemas operativos que
utilizan este tipo de multitareas son los UNIX y sus clones (Linux, etc),
Windows NT, etc.
8. Multitarea Real
Multitarea en donde el SO ejecuta los procesos realmente al mismo tiempo
haciendo uso de múltiples procesadores (2 o más). La ejecución realmente
se realiza en distintos procesadores para cada proceso o tarea. Obviamente
en el caso de que los procesos o tareas sean más que la cantidad de
procesadores, éstos comienzan a ejecutarse en procesadores "en uso" en la
forma de multitareas preferente. Todos los sistemas operativos modernos
soportan esta capacidad.
9. Multiprogramación
Es la técnica que permite que dos o mas programas ocupen la misma
unidad de memoria principal y que sean ejecutados al mismo tiempo.
La multiprogramación se refiere a dos o mas programas corriendo o
procesándose al mismo tiempo; La multiprogramación se controla a través
del sistema operativo, el cual observa los programas y los vigila hasta que
estén concluidos.
El numero de programas que pueden multiprogramarse en forma efectiva,
depende de una combinación de la cantidad de memoria, de la velocidad
de la CPU y del número y velocidad de los recursos periféricos que tenga
conectados, así como de la eficiencia del SO.
10. Principios de Concurrencia
En un sistema multiprogramado con un único procesador, los procesos se
intercalan en el tiempo aparentando una ejecución simultánea. Aunque no
se logra un procesamiento paralelo y produce una sobrecarga en los
intercambios de procesos, la ejecución intercalada produce beneficios en la
eficiencia del procesamiento y en la estructuración de los programas.
11. Principios de Concurrencia
La concurrencia es el punto clave en los conceptos de multitarea,
multiprogramación y multiproceso, la concurrencia comprende un gran
numero de cuestiones de diseño incluyendo la comunicación entre
procesos, la compartición y competencia por los recursos, la sincronización
de la ejecución de varios procesos y la asignación del procesador a los
procesos, la concurrencia puede presentarse en tres contextos diferentes:
Varias aplicaciones
Aplicaciones estructuradas
Estructura del sistema operativo
12. Varias aplicaciones
En este caso el tiempo de procesador de una máquina es compartido
dinámicamente entre varios trabajos o aplicaciones activas.
13. Estructura del sistema operativo
Como resultado de la aplicación de la estructuración en el diseño del
propio SO, de forma que este se implemente como un conjunto de
procesos.
14. LABORES DEL SISTEMA OPERATIVO
Elementos de gestión y diseño que surgen por causa de la concurrencia:
1. El sistema operativo debe seguir a los distintos procesos activos.
2. El sistema operativo debe asignar y retirar los distintos recursos a cada
proceso activo, entre estos se incluyen:
Tiempo de procesador
Memoria
Archivos
Dispositivos de E/S
3. El sistema operativo debe proteger los datos y los recursos físicos de
cada proceso contra injerencias* no intencionadas de otros procesos.
4. Los resultados de un proceso deben ser independientes de la velocidad
a la que se realiza la ejecución de otros procesos concurrentes.
* Acción y resultado de injerirse o entrometerse en asuntos ajenos
15. Comunicación y Sincronización de Procesos
Puede verse la concurrencia de procesos como una ejecución simultánea de
varios procesos. Si tenemos un multiprocesador la concurrencia parece
clara, en un momento dado cada procesador ejecuta un proceso. Se puede
ampliar el concepto de concurrencia si entendemos el procesado
concurrente del sistema en conjunto: Varios procesos que se vean en un
estado intermedio entre su estado inicial y final.
Cooperación entre Procesos:
La velocidad de un proceso depende de la frecuencia de la interrupción
asociada a cada uno de ellos que un proceso se ejecuta asíncronamente con
respecto a otro, es decir, sus ejecuciones son independientes. Sin embargo,
hay ciertos instantes en lo que los procesos deben sincronizar sus
actividades. Son estos puntos a partir de los cuales un proceso no puede
progresar hasta que otro haya completado algún tipo de actividad.
16. Posibilidad de interacción de procesos
Las posibilidadades de interacción de los procesos pueden clasificarse en
función del nivel de conocimiento que cada proceso requieren la existencia
de los demás.
Un proceso no tiene en absoluto conocimiento de la existencia de los
demás.
Que los procesos tengan un conocimiento indirecto de los otros
procesos.
Tiene lugar cuando los procesos tienen conocimiento directo unos de
otros por haber sido diseñados para trabajar conjuntamente el alguna
actividad.
17. Necesidad de sincronización de los procesos:
región critica y exclusión mutua
La sincronización entre procesos puede definirse como la necesidad que
tienen algunos procesos de bloquearse en determinadas circunstancias y
ser despertados cuando ocurren ciertos eventos. Un caso típico que
muestra la necesidad de sincronización entre procesos es cuando un
proceso inicia una lectura y va a utilizar en la siguiente instrucción la
información leída. En este caso el proceso debe esperar a que se termine la
operación de Entrada/Salida para continuar.
Gestión de procesos
Ejecución:
18. La Exclusión Mutua
La exclusión mutua la podríamos definir como una operación de control
que permite la coordinación de procesos concurrentes (Comunicación
requerida entre dos o mas procesos), y que tiene la capacidad de prohibir a
los demás procesos realizar una acción cuando un proceso haya obtenido el
permiso.
Soluciones software para la Exclusión mutua:
Una manera es dejar la responsabilidad a los procesos que se deseen
ejecutar concurrentemente, de esta manera los procesos deben coordinarse
unos con otros para cumplir la exclusión mutua sin ayuda alguna, aunque
estas soluciones son propensas a errores y a una fuerte carga de proceso
(Algunos ejemplos de estas son: Algoritmo de Dekker y Algoritmo de
Peterson).
19. Algoritmo de Dekker
Es un algoritmo de programación concurrente para exclusión mutua, que
permite a dos procesos o hilos de ejecución compartir un recurso sin
conflictos. Fue uno de los primeros algoritmos de exclusión mutua
inventados, implementado por Edsger Diikstra.
Si ambos procesos intentan acceder a la sección crítica simultáneamente,
el algoritmo elige un proceso según una variable turno. Si el otro proceso
está ejecutando en su sección crítica, deberá esperar su finalización.
Existen cinco versiones del algoritmo Dekker, teniendo ciertos fallos los
primeros cuatro. La versión 5 es la que trabaja más eficientemente, siendo
una combinación de la 1 y la 4.
20. Algoritmo de Dekker
Versión 1: Alternancia estricta. Garantiza la exclusión mutua, pero su
desventaja es que acopla los procesos fuertemente, esto significa que los
procesos lentos atrasan a los procesos rápidos.
Versión 2: Problema interbloqueo. No existe la alternancia, aunque ambos
procesos caen a un mismo estado y nunca salen de ahí.
Versión 3: Colisión región crítica no garantiza la exclusión mutua. Este
algoritmo no evita que dos procesos puedan acceder al mismo tiempo a la
región critica.
Versión 4: Postergación indefinida. Aunque los procesos no están en
interbloqueo, un proceso o varios se quedan esperando a que suceda un
evento que tal vez nunca suceda.
21. Algoritmo de Peterson
Peterson desarrolló el primer algoritmo (1981) para dos procesos, fue una
simplificación del algoritmo de Dekker para dos procesos. Posteriormente
este algoritmo fue generalizado para que funcionara para N procesos. En el
algoritmo para N procesos las variables c[i] además de valer "verdadero" y
"falso", pueden valer "en sección critica” y turno desde 1 hasta N. El
procedimiento es una generalización de este c[i], que es un array y turno,
que solo puede valer 1 o 2. Este algoritmo garantiza la exclusión mutua
debido al uso de una variable compartida: turno, que se chequea cada vez.
Inicialmente, c[0]=c[1]=falso, y el valor de turno no tiene relevancia (pero
debe ser 0 o 1). Para entrar en la sección crítica, el proceso P[i] primero
asigna el valor verdadero a c[i] y luego afirma que es el turno del otro
proceso para entrar si así lo desea (turno = j). Si ambos procesos tratan de
entrar a la vez, se asignará turno como i y j aproximadamente al mismo
tiempo. Sólo una de estas asignaciones durará; la otra ocurrirá, pero será
reemplazada de inmediato. El valor eventual de turno decide a cuál de los
dos procesos se le permitirá entrar primero en su sección crítica.
22. Semáforos
Los semáforos pueden contemplarse como variables que tienen un valor
entero sobre las que se definen las tres operaciones siguientes:
Un semáforo puede inicializarse con un valor negativo. Un semáforo
puede inicializarse con un valor no negativo.
La operación WAIT decrementa el valor del semáforo. Si el valor se
hace negativo, el proceso que ejecuta WAIT queda bloqueado.
La operación SIGNAL incrementa el valor del semáforo. Si el valor no
es positivo, se desbloquea a un proceso bloqueado previamente por una
operación WAIT.
23. Monitores
Un monitor es, esencialmente, una colección de datos y de procedimientos
para su manipulación junto con una secuencia de inicialización. Las
variables de datos globales son generalmente privadas al monitor por lo
que solo son accesibles a los procedimientos de este. Los procedimientos
del monitor podrán ser públicos o privados. Un monitor puede
considerarse como una estructura estática que se activa únicamente
cuando alguno de sus procedimientos públicos es llamado por un proceso
en ejecución y se dice, entonces, que el proceso en cuestión entra o tiene
acceso al monitor. Solamente un proceso puede estar ejecutándose en el
monitor en un instante determinado. Una estructura de datos compartida
puede así protegerse situándola dentro de un monitor que ofrecerá un
servicio de exclusión mutua para dicha estructura. Para que resulten útiles
en el procesamiento concurrente, los monitores deben incluir alguna
herramienta de sincronización de forma que se impida el acceso al monitor
a un proceso cuando otro esta ejecutando dentro de el. Esta sincronización
se consigue por medio paso de mensajes.