Sistema Linux
Sistema Linux
Sistema Linux
Sistemas Operativos
Capítulo #3
ADMINISTRACIÓN DE PROCESOS, LINUX Y WINDOWS
Participante:
Rodolfo Maracallo Alcantara
Matricula:
2020-10327
Facilitador:
José Doñe
Fecha:
17/9/20
A
A
Sincronización entre procesos.
Comunicación entre procesos
La espina dorsal de los sistemas distribuidos son los mecanismos de comunicación entre
procesos (interprocess communication o IPC): la posibilidad de que procesos separados e
independientes (como podrá recordar el lector, los procesos son representaciones en tiempo
de ejecución de programas) se comuniquen entre sí para colaborar en una tarea. En este
capítulo, se van a ver los fundamentos, características, paradigmas e implementaciones de
los mecanismos de comunicación entre procesos.
La Figura 2.1 ilustra un mecanismo básico de comunicación entre procesos: Dos procesos
independientes, con la posibilidad ejecutarse en máquinas separadas, intercambian datos
sobre una red de comunicaciones. En este caso, el proceso 1 actúa como emisor, que
transmite datos al proceso 2, el receptor.
FIGURA 2.1: Comunicación entre procesos
Proceso 1, Proceso 2, Emisor, Receptor, Datos
En sistemas distribuidos, dos o más procesos establecen una comunicación entre ellos por
medio de un protocolo -un conjunto de reglas que deben ser observadas por los
participantes en la comunicación de los datos- acordado por los procesos. Un proceso puede
ser emisor en determinados puntos durante el protocolo y receptor en otros. Cuando la
comunicación es desde un proceso a únicamente otro proceso, el modelo de comunicación
entre procesos se dice que es unidifusión o unicast. Cuando la comunicación es desde un
proceso con un grupo de procesos, el mecanismo de comunicación se denomina
multidifusión o multicast, que será tratado en el Capítulo 6. La Figura 2.2 ilustra el
concepto de estos dos tipos de IPC.
FIGURA 2.2: Unicast y multicast
Los sistemas operativos actuales, como UNIX y Windows proporcionan funcionalidades
para la comunicación entre procesos. Llamaremos a estas funcionalidades mecanismos de
comunicación entre procesos a nivel de sistema operativo, para distinguirlos de los
mecanismos de comunicación de alto nivel. Los mecanismos de comunicación a nivel de
sistema operativo incluyen colas de mensajes, semáforos, y regiones de memoria
compartida. (Si el lector no ha realizado un curso de sistemas operativos, no se preocupe si
no le resultan familiares estos términos; no van a ser casos de estudio en este libro.) Es
posible desarrollar software de red usando directamente estas funcionalidades a nivel de
sistema operativo. Ejemplos de estos programas son los manejadores (drivers) de red y los
programas de evaluación de prestaciones.
Se pueden desarrollar también aplicaciones distribuidas muy rudimentarias, aunque
normalmente no se hace, debido a que la complejidad típica de estas aplicaciones requiere
el uso de algún tipo de abstracción para separar al programador de los detalles a nivel de
sistema operativo. El lector puede encontrar más información sobre mecanismos de
comunicación a nivel de sistema operativo en libros sobre dichos sistemas operativos.
Mecanismo de sincronización.
Para representar los procesos, un sistema operativo multiprogramado debe almacenar
información en base a la cual:
Identificar cada proceso. Se utiliza un identificador del proceso, que suele ser un entero.
Representar el estado de cada proceso para mantener el grafo de transición de estados.
Normalmente los estados se representan mediante colas de procesos.
Planificar el siguiente proceso que entre en la CPU (scheduling). Se requiere información
que permita aplicar los criterios de planificación (prioridad, quantum, etc).
Contabilizar el uso de recursos por el proceso (tiempo consumido de CPU, tiempo de
ejecución del proceso, tiempos máximos asignados, identificador de usuario). Parte de esta
información puede ser útil para la planificación.
Gestionar el contexto de los procesos. Por cada proceso hay que almacenar el estado del
procesador, de la pila y de los otros recursos (memoria y entrada/salida). En un cambio de
contexto hay que guardar el contexto del proceso que abandona la ejecución y restaurar el
contexto del proceso planificado.
Gestionar la memoria. Punteros a tablas de páginas y otra información de la que
hablaremos en su momento.
Soportar la entrada/salida. Peticiones pendientes, dispositivos asignados, tabla de canales,
etc.
Esta información no tiene por qué estar concentrada en una estructura de datos única para
cada proceso. Cómo se almacene dependerá de la estructura del sistema operativo. Por
ejemplo, en los sistemas por capas, la información de un proceso estará segmentada a través
de las capas. Sin embargo, conceptualmente podemos suponer una estructura, que
denominaremos Bloque de Control del Proceso o PCB (Process Control Block), que
almacena la información del proceso. Los PCBs se enlazan para formar listas encadenadas
(Figura B), por lo que el PCB incluye uno o más apuntadores. La disciplina de acceso a los
PCBs puede ser diversa (FCFS, en base a la prioridad, etc). Así, la gestión de procesos en el
sistema operativo se puede representar mediante un conjunto de colas de PCBs. Habrá una
cola para los procesos que estén en estado preparado para ejecución, una cola para cada
condición de bloqueo, e incluso, para generalizar, se puede considerar una cola de procesos
en ejecución (por cada CPU).
Figura B Una lista de PCBs de encadenado simple.
De esta forma, podemos definir el sistema operativo como un modelo de procesos que se
representa mediante un sistema de colas, según se muestra a continuación.
Sección critica.
Se denomina región crítica, (sección y región críticas son denominaciones equivalentes) en
programación concurrente de ciencias de la computación, a la porción de código de un
programa de ordenador en la que se accede a un recurso compartido (estructura de datos o
dispositivo) que no debe ser accedido por más de un proceso o hilo en ejecución. La
sección crítica por lo general termina en un tiempo determinado y el hilo, proceso o tarea
sólo tendrá que esperar un período determinado de tiempo para entrar. Se necesita un
mecanismo de sincronización en la entrada y salida de la sección crítica para asegurar la
utilización en exclusiva del recurso, por ejemplo, un semáforo, monitores, el algoritmo de
Dekker y Peterson, los candados.
El acceso concurrente se controla teniendo cuidado de las variables que se modifican dentro
y fuera de la sección crítica. La sección crítica se utiliza por lo general cuando un programa
multihilo actualiza múltiples variables sin un hilo de ejecución separado que lleve los
cambios conflictivos a esos datos. Una situación similar, la sección crítica puede ser
utilizada para asegurarse de que un recurso compartido, por ejemplo, una impresora, pueda
ser accedida por un solo proceso a la vez.
La manera en cómo se implementan las secciones puede variar dependiendo de los diversos
sistemas operativos.
Semáforos.
Funcionamiento de los semáforos
Dos o más procesos pueden cooperar por medio de simples señales, de forma que se pueda
obligar a detenerse a un proceso en una posición determinada hasta que reciba una señal
específica. Cualquier requisito complicado de coordinación puede satisfacerse por medio de
la estructura de señales adecuada. Para la señalización, se usan variables especiales
llamadas semáforos. Para transmitir una señal por el semáforo, los procesos ejecutan la
primitiva signal(s). Para recibir una señal del semáforo, los procesos ejecutan la primitiva
wait(s); si la señal correspondiente aún no se ha transmitido, el proceso es suspendido hasta
que tenga lugar la transmisión. Para lograr el efecto deseado, se pueden contemplar los
semáforos como variables que tienen un valor entero sobre el que se definen las tres
operaciones siguientes:
1- Un semáforo debe inicializarse con un valor no negativo.
2- La operación wait decrementa el valor del semáforo. Si el valor del semáforo se
hace negativo, el proceso que ejecuta el wait se bloquea.
3- La operación signal incrementa el valor del semáforo. Si el valor no es positivo, se
desbloquea a un proceso bloqueado por una posición wait.
Las primitivas wait y signal se suponen atómicas, es decir, no pueden ser interrumpidas y
cada rutina puede considerarse como un paso indivisible. Una versión más limitada es el
semáforo binario, que sólo puede tomar los valores 0 y 1. En principio los semáforos
binarios son más sencillos de implementar y tienen la misma potencia de expresión que los
semáforos generales. Tanto en los semáforos como en los semáforos binarios se emplea una
cola para mantener los procesos esperando en el semáforo. La política más equitativa
mediante la cual se quitan los procesos de dicha cola es la FIFO. La única exigencia estricta
es que un proceso no debe quedar retenido en la cola de un semáforo indefinidamente
porque otros procesos tengan preferencia.
Generalmente operadores como WAIT y SIGNAL operan en los semáforos de la siguiente
manera. Cuando un proceso ejecuta un operador WAIT que tiene un valor de semáforo en
0, ese proceso se bloquea; si el valor es mayor que cero, el valor del semáforo es
disminuido en 1 y el proceso continuo. Cuando un proceso ejecuta un operador SIGNAL y
hay procesos bloqueados (WAITING), uno de estos procesos es activado (puesto en la cola
de listos). Si no hay procesos esperando el valor del semáforo se incrementa en 1. Se asume
que procesos bloqueados por semáforos pierden el procesador y entran en una cola de
espera (WAITING QUEUE) en vez de producir BUSY WAITING. También se asume que
la cola de espera es FIFO.
Monitores.
Los semáforos son una herramienta básica, pero potente y flexible, para hacer cumplir la
exclusión mutua y coordinar procesos. Sin embargo, puede resultar muy difícil construir un
programa correcto por medio de semáforos. La dificultad está en que las operaciones wait y
signal deben distribuirse por todo el programa y no es fácil advertir el efecto global de estas
operaciones sobre los semáforos a los que afectan. En los semáforos, tanto la exclusión
mutua como la sincronización son responsabilidades del programador. Los monitores son
estructuras de un lenguaje de programación que ofrecen una funcionalidad equivalente a la
de los semáforos y que son más fáciles de controlar.
Los monitores fueron propuestos por Brich Hansen y mejorados por Hoare para poder
utilizar procesos automáticos de sincronización. Un módulo monitor encapsula la mutua
exclusión de datos y procedimientos que pueden acceder a los datos protegidos. Los
usuarios pueden hacer llamadas a estos procedimientos usando al monitor como una tabla
de estado para determinar cuándo proceder y cuando suspender operaciones.
Monitores con señales
Un monitor es un módulo de software que consta de uno o más procedimientos, una
secuencia de inicialización y unos datos locales. Las características básicas de un monitor
son las siguientes:
1- Las variables de datos locales están sólo accesibles para los procedimientos del
monitor y no para procedimientos externos.
2- n proceso entra en el monitor invocando a uno de sus procedimientos.
3- Sólo un proceso puede estar ejecutando en el monitor en un instante dado; cualquier
otro proceso que haya invocado al monitor quedará suspendido mientras espera que
el monitor esté disponible.
Solamente una llamada a un módulo monitor puede ser activada por vez. Esto protege a los
datos dentro del monitor de accesos simultáneos de múltiples usuarios. Los usuarios que
intentan acceder al monitor mientras este está ocupado son bloqueados en una cola de
entrada al monitor.
CWAIT(c): Suspende la ejecución del proceso llamado bajo la condición c. El monitor está
ahora disponible para ser usado por otro proceso.
CSIGNAL(c): Reanuda la ejecución de algún proceso suspendido después de un CWAIT
() bajo la misma condición. Si hay varios procesos, elige uno de ellos; si no hay ninguno,
no hace nada.
Los operadores de sincronización del monitor son llamados CWAIT () y CSIGNAL () de la
misma manera que en programas basados en semáforos. Sin embargo, variables de
condición son usadas en lugar de semáforos y su comportamiento es diferente. Por ejemplo,
definen simplemente la cola de espera y no tienen valores numéricos como los semáforos.
En cualquier momento que una condición variable CWAIT () es encontrada, el proceso
ejecutando el CWAIT () está siempre bloqueado. En cualquier momento que un CSIGNAL
() es encontrado en una condición variable, un proceso esperando en la cola de condiciones
variables (el primero si es FIFO) es activado (puesto en la cola de listos). Si no hay
procesos esperando, el operador CSIGNAL () es ignorado.
Es importante destacar que un proceso con la marca CSIGNAL () debe ser el próximo en
entrar al monitor para que las condiciones existentes cuando ocurrió el CSIGNAL () no
sean cambiadas cuando éste entre al monitor. También, cuando no hay procesos bloqueados
en la cola de condiciones variables CSIGNAL (), pero hay procesos bloqueados en la cola
de entrada al monitor, CSIGNAL () activará “la cabeza” de la cola de entrada al monitor
pasándole el control del monitor.
Si hay al menos un proceso en una cola de condición, un proceso de dicha cola deberá
ejecutar en cuanto otro proceso ejecute un CSIGNAL () para la condición. Así pues, el
proceso que ejecuta el CSIGNAL () debe salir inmediatamente del monitor o suspenderse
en el monitor. Son varios los inconvenientes de esta solución:
1- Si el proceso que ejecuta el CSIGNAL () no abandona el monitor, hacen falta dos
cambios de contexto adicionales: uno para suspender el proceso y otro para
reanudarlo cuando el monitor quede disponible.
2- Cuando se ejecuta un CSIGNAL (), debe activarse inmediatamente un proceso de la
cola de la condición correspondiente y el planificador debe asegurarse de que
ningún otro proceso entre al monitor antes de la activación. Si no es así, la
condición bajo la que se ha activado el proceso podría cambiar.
Se puede utilizar el paso de mensajes para cumplir con la exclusión mutua. Esta técnica
dice que, si hay más de un proceso ejecutando la acción receive concurrentemente,
entonces:
Si hay un mensaje, se entrega sólo a uno de los procesos y los otros se bloquean.
Si el buzón está vacío, todos los procesos se bloquean. Cuando haya un mensaje disponible,
sólo se activa y toma el mensaje uno de los procesos bloqueados. Una vez que un proceso
ha conseguido el mensaje, ejecuta su sección crítica y, después, devuelve el mensaje al
buzón. De este modo, el mensaje funciona como un testigo (token) que se pasa de un
proceso a otro.
Regiones críticas.
Los puntos de entrada de un recurso indican la cantidad de procesos que pueden utilizar
simultáneamente al mismo. Si un recurso tiene sólo un punto de entrada, se lo denomina
recurso crítico o recurso no compartible.
Región crítica de un proceso es la fase o etapa en la vida de ese proceso concurrente en la
cual accede a un recurso crítico para modificarlo o alterarlo.
El uso adecuado de la concurrencia entre procesos exige la capacidad de definir secciones
críticas y hacer cumplir la exclusión mutua. Cualquier servicio o capacidad que dé soporte
para la exclusión mutua debe cumplir con un protocolo de sincronización, que tiene los
requisitos siguientes:
Debe cumplirse la exclusión mutua: sólo un proceso de entre todos los que poseen
secciones críticas por el mismo recurso u objeto compartido, debe tener permiso para entrar
en ella en un instante dado.
Un proceso que se interrumpe en una sección no crítica debe hacerlo sin estorbar a los
otros. Es decir que si se cuelga un proceso que está usando un recurso, los demás procesos
que esperan deben poder acceder al recurso de todas formas (el S.O. mata al proceso que se
colgó y así libera al recurso).
No se puede demorar indefinidamente la entrada de un proceso a un cierto recurso; no debe
permitirse el interbloqueo y la inanición. Todos los procesos deben poder acceder al recurso
que solicitan, sino se van a morir sin usarlo y no es justo.
Cuando ningún proceso está en su sección crítica, cualquier proceso que solicite entrar en
la suya debe poder hacerlo sin dilatación. Es decir, si nadie está usando un cierto recurso,
entonces se le otorga al primer proceso que lo solicite.
No se pueden hacer suposiciones sobre la velocidad relativa de los procesos o su número
(cantidad de procesadores). Nunca se puede saber a priori si a un proceso le falta mucho o
poco para terminar.
Un proceso permanece en su sección crítica sólo por un tiempo finito. Esto sirve para
evitar que un proceso se quede con un recurso por mucho tiempo y para que un recurso no
se quede trabado sin sentido.
problemas clásicos de la comunicación entre procesos.
Comunicación entre procesos: Los procesos que ejecutan de forma concurrente en un
sistema se pueden clasificar como procesos independientes o cooperantes. Un proceso
independiente es aquel que ejecuta sin requerir la ayuda o cooperación de otros procesos.
Un claro ejemplo de procesos independientes son los diferentes intérpretes de mandatos que
se ejecutan de forma simultánea en un sistema. Los procesos son cooperantes cuando están
diseñados para trabajar conjuntamente en alguna actividad, para lo que deben ser capaces
de comunicarse e interactuar entre ellos. Tanto si los procesos son independientes como
cooperantes, pueden producirse una serie de interacciones entre ellos. Estas interacciones
pueden ser de dos tipos:
El problema de la sección crítica: Este es uno de los problemas que con mayor frecuencia
aparece cuando se ejecutan procesos concurrentes tanto si son cooperantes como
independientes. Considérese un sistema compuesto por n procesos {P1, P2, ..., PN} en el
que cada uno tiene un fragmento de código, que se denomina sección crítica. Dentro de la
sección crítica, los procesos pueden estar accediendo y modificando variables comunes,
registros de una base de datos, un archivo, en general cualquier recurso compartido. La
característica más importante de este sistema es que cuando un proceso se encuentra
ejecutando código de la sección crítica, ningún otro proceso puede ejecutar en su sección.