1) ¿Cuáles
son los problemas clásicos de Comunicación y Sincronización de Procesos?
* La Sección Crítica:
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. Para resolver el problema de la sección
crítica es necesario utilizar algún mecanismo
de sincronización que permita a los procesos cooperar entre ellos sin
problemas. Este mecanismo debe proteger el código de la sección crítica y su
funcionamiento básico es el siguiente:
· Cada
proceso debe solicitar permiso para entrar en la sección crítica mediante algún
fragmento de código, que se denomina de forma genérica entrada en la sección crítica.
. Cuando
un proceso sale de la sección crítica debe indicarlo mediante otro fragmento de
código, que se denomina salida de la
sección crítica. Este fragmento permitirá que otros procesos entren a
ejecutar el código de la sección crítica.
*Productor-Consumidor:
El
problema del productor-consumidor es uno de los problemas más habituales que
surge cuando se programan aplicaciones utilizando procesos concurrentes. En
este tipo de problemas, uno o más procesos, que se denominan productores, generan cierto tipo de
datos que son utilizados o consumidos por otros procesos, que se denominan consumidores. Un claro ejemplo de este tipo de problemas es el del compilador. En
este ejemplo el compilador hace las funciones de productor al generar el código
ensamblador que consumirá el proceso ensamblador para generar el código máquina.
En esta clase de problemas es necesario disponer de algún mecanismo de
comunicación que permita a los procesos productor y consumidor intercambiar
información. Ambos procesos, además, deben sincronizar su acceso al mecanismo
de comunicación para que la interacción entre ellos no sea problemática: cuando
el mecanismo de comunicación se llene, el proceso productor se deberá quedar
bloqueado hasta que haya hueco para seguir insertando elementos. A su vez, el
proceso consumidor deberá quedarse bloqueado cuando el mecanismo de
comunicación este vacío, ya que en este caso no podrá continuar su ejecución al
no disponer de información a consumir. Por tanto, este tipo de problema
requiere servicios para que los procesos puedan comunicarse y servicios para
que se sincronicen a la hora de acceder al mecanismo de comunicación.
* Los lectores-escritores:
En este
problema existe un determinado objeto, que puede ser un archivo, un registro
dentro de un archivo, etc., que va a ser utilizado y compartido por una serie
de procesos concurrentes. Algunos de estos procesos sólo van a acceder al
objeto sin modificarlo, mientras que otros van a acceder al objeto para
modificar su contenido. Esta actualización implica leerlo, modificar su
contenido y escribirlo. A los primeros procesos se les denomina lectores y a los segundos se les
denomina escritores. En este
tipo de problemas existe una serie de restricciones que han de seguirse:
·
Sólo se permite que un escritor tenga acceso
al objeto al mismo tiempo. Mientras el escritor esté accediendo al objeto,
ningún otro proceso lector ni escritor podrá acceder a él.
·
Se permite, sin embargo, que múltiples
lectores tengan acceso al objeto, ya que ellos nunca van a modificar el
contenido del mismo.
En este
tipo de problemas es necesario disponer de servicios de sincronización que
permitan a los procesos lectores y escritores sincronizarse adecuadamente en el
acceso al objeto.
Ejemplo:
Problemas:
Existe un recurso (archivo, registro, etc.) que va a ser utilizado y compartido
por una serie de procesos concurrentes, algunos procesos acceden sin modificarlo (lectores). Otros procesos
acceden para modificarlo (escritores). Restricciones en estos problemas: 1 escritor exclusivamente
Múltiples lectores Se requieren servicios de sincronización para que lectores y
escritores se sincronicen en el acceso al recurso.
*Comunicación
Cliente-Servidor:
En el
modelo cliente-servidor, los procesos llamados servidores ofrecen una serie de
servicios a otros procesos que se denominan clientes. El proceso servidor puede
residir en la misma máquina que el cliente o en una distinta, en cuyo caso la
comunicación deberá realizarse a través de una red de interconexión. Muchas
aplicaciones y servicios de red, como el correo electrónico y la transferencia
de archivos, se basan en este modelo.
En este
tipo de aplicaciones es necesario que el sistema operativo ofrezca servicios
que permitan comunicarse a los procesos cliente y servidor. Cuando los procesos
ejecutan en la misma máquina, se pueden emplear técnicas basadas en memoria
compartida o archivos. Sin embargo, este modelo de comunicación suele emplearse
en aplicaciones que ejecutan en computadores que no comparten memoria y, por
tanto, se usan técnicas basadas en paso de mensajes.
Algunos ejemplos
de aplicación computacionales del modelo cliente servidor son: El correo electrónico, un servidor de
impresión, y la World Wide Web.
2). Mencione ¿Cuáles son los mecanismos de
Sincronización entre Proceso?
*Tuberías (pipes):
Una tubería es un mecanismo
de comunicación y sincronización. Desde el punto de vista de su utilización, es
como un seudoarchivo mantenido por el sistema operativo. Conceptualmente, cada
proceso ve la tubería como un conducto con dos extremos, uno de los cuales se
utiliza para escribir o insertar datos y el otro para extraer o leer datos de
la tubería. La escritura se realiza mediante el servicio que se utiliza para
escribir datos en un archivo. De igual forma, la lectura se lleva a cabo
mediante el servicio que se emplea para leer de un archivo
Ejemplos:
* Semáforos:
Un
semáforo es un mecanismo de sincronización que se utiliza generalmente en
sistemas con memoria compartida, bien sea un monoprocesador o un
multiprocesador. Su uso en un multicomputador depende del sistema operativo en
particular. Un semáforo es un objeto con un valor entero al que se le puede asignar
un valor inicial no negativo y al que sólo se puede acceder utilizando dos
operaciones atómicas: wait y signal (también llamadas Down o up,
respectivamente).
Ejemplo:
Los semáforos pueden ser usados
para diferentes propósitos, entre ellos:
·
Implementar cierres de
exclusión mutua o locks
·
Barreras
·
Permitir a un máximo de N threads (hilos) acceder a un recurso,
inicializando el semáforo en N
·
Notificación. Inicializando el semáforo en 0 puede
usarse para comunicación entre threads sobre la disponibilidad de un recurso
En el siguiente ejemplo se crean y ejecutan n procesos
que intentarán entrar en su sección crítica cada vez que puedan, y lo lograrán
siempre de a uno por vez, gracias al uso del semáforo s inicializado en 1. El
mismo tiene la misma función que un lock.
Const int
n /* número de procesos */
Variable
semáforo s; /* declaración de la variable semáforo de valor entero*/
Inicia (s,
1) /* Inicializa un semáforo de nombre
s con valor 1 */
Void P
(int i)
{
While (cierto)
{
P(s) /* En semáforos binarios, lo correcto es
poner un P(s) antes de entrar en
La sección crítica, para
restringir el uso de esta región del código*/
/*
SECCIÓN CRÍTICA */
V(s) /* Tras la sección
crítica, volvemos a poner el semáforo a 1 para que otro
Proceso pueda usarla */
/*
RESTO DEL CÓDIGO */
}
}
Int main
()
{
Comenzar-procesos (P (1), P (2),..., P(n));
*Mutex:
Los
mutex y las variables condicionales son mecanismos especialmente concebidos
para la sincronización de procesos ligeros. Un mutex es el mecanismo de
sincronización de procesos ligeros más sencillo y eficiente. Los mutex se
emplean para obtener acceso exclusivo a recursos compartidos y para asegurar la
exclusión mutua sobre secciones críticas.
Un Mutex
consiste en una especie de semáforo binario con dos estados, cerrado y no
cerrado. Un Mutex es un acceso que permite a los hilos asegurar la integridad
de un recurso compartido al que tienen acceso. Tienen dos estados: Bloqueado y
Desbloqueado.
Ejemplo:
Un
ejemplo de de utilización de Mutex es aquel en el que un hilo A y un hilo B
están compartiendo un recurso típico, como puede ser una variable global. El
hilo A bloquea el Mutex, con lo que obtiene el acceso a la variable. Cuando el
hilo B intenta bloquear el Mutex, el hilo B es puesto a la espera, puesto que
le Mutex ya ha sido bloqueado antes. Cuando el hilo A finaliza el acceso a la
variable global, desbloquea el Mutex. Cuando esto sucede, el hilo B continuara
la ejecución adquiriendo el bloqueo, pudiendo entonces acceder a la variable.
* Interbloqueo:
Un
interbloqueo supone un bloqueo permanente de un conjunto de procesos que
compiten por recursos o bien se comunican o sincronizan entre sí. Los interbloqueos que aparecen cuando se
utilizan mecanismos de comunicación y sincronización se deben a un mal uso de
los mismos.
Ejemplos:
Proceso
P1 Proceso P2
Solicita (C) Solicita (l)
Solicita
(l) Solicita
(C)
Uso de
rec. Uso de
rec.
Libera (l) Libera (C)
Libera (C) Libera (l)
O cuando
dos procesos compiten por dos recursos que necesitan para funcionar, que solo
pueden ser usador por un proceso a la vez.
3). Defina ¿Qué es POSIX? Y ¿Cómo
se relaciona con la Comunicación y
Sincronización de Procesos?
POSIX: Es un estándar de interfaces de
Sistema Operativo, basado en el popular sistema operativo UNIX. Su principal
objetivo es permitir la portabilidad de aplicaciones a nivel de código fuente,
es decir, que sea posible portar una aplicación de un computador a otro sin más
que recompilar su código. Junto a las interfaces de servicios del sistema, se
estandarizan también perfiles de entornos de aplicaciones que permitirán a los
implementadores desarrollar Sistemas Operativos POSIX de tiempo real para una
gran variedad de plataformas, desde los sistemas empotrados pequeños hasta los
sistemas de tiempo real grandes. El estándar define interfaces en diferentes lenguajes de programación. En
particular, las interfaces de tiempo real están siendo definidas para C y Ada,
que son los lenguajes estándar de programación más importantes para los
sistemas prácticos de tiempo real.
POSIX se relaciona
con la Comunicación de procesos,
especificando un mecanismo sencillo de colas de mensajes para la comunicación
entre procesos. Las colas de mensajes están identificadas por un nombre
perteneciente a un espacio de nombres dependiente de la implementación.
POSIX se relaciona con la Sincronización de
procesos, definiendo funciones para permitir la sincronización de procesos a
través de semáforos contadores.
Ejemplos:
El
número de semáforos disponibles es fijo (constante NUM_SEM). Cada semáforo
tiene asociado un nombre que consiste en una cadena de caracteres con un tamaño
máximo igual a MAX_NOM_SEM (incluyendo el carácter nulo de terminación de la
cadena). Comunicación y sincronización de procesos.
Cuando
se crea un semáforo, el proceso obtiene un descriptor (similar al descriptor de
archivo de POSIX) que le permite acceder al mismo. Si ya existe un semáforo con
ese nombre, se devuelve un error. En caso de que no exista colisión, se debe
comprobar si se ha alcanzado el número máximo de semáforos en el sistema. Si
esto ocurre, se debe bloquear al proceso hasta que se elimine algún semáforo.
La operación que crea el semáforo también lo deja abierto para poder ser usado.
Para
poder usar un semáforo ya existente se debe abrir especificando su nombre. El
proceso obtiene un descriptor asociado al mismo, cada proceso tiene asociado un
conjunto de descriptores a los semáforos que está usando. El número de
descriptores por proceso está limitado a NUM_SEM_PROC. Si al abrir o crear un
semáforo no hay ningún descriptor libre, se devuelve un error. Las primitivas
de uso del semáforo (signal y wait) tienen básicamente la semántica
convencional. Ambas reciben como parámetro un descriptor de semáforo. La única
característica un poco especial es que la primitiva signal incluye como
argumento el número de unidades que se incrementa el semáforo.
Por
tanto, esta llamada puede causar el desbloqueo de varios procesos, cuando un
proceso no necesita usar un semáforo, lo cierra.
El
semáforo se eliminará realmente cuando no haya ningún proceso que lo utilice, o
sea, no haya ningún descriptor asociado al semáforo. En el momento de la
liberación real es cuando hay que comprobar si había algún proceso bloqueado
esperando para crear un semáforo debido a que se había alcanzado el número máximo
de semáforos en el sistema.
Señales POSIX permiten:
v Un proceso puede bloquearse
mediante el servicio “pause” y esperar una señal de otro proceso enviada con
“Kill”.
v Desventajas: Las señales tienen
comportamientos asíncronos, podría recibir una señal en cualquier momento aunque no la espere.
v Las señales no se encolan, solo
la última de un tipo, con lo cual se podrían perder eventos de sincronización
importantes.
v No se pueden usar para
sincronizar procesos, excepto casos muy simples.
Resumen sobre la Unidad 06:
La comunicación entre procesos es una función básica de los sistemas operativos. Los procesos pueden comunicarse entre sí a través de compartir espacios de
memoria, ya sean variables compartidas o buffers, o a través de las
herramientas provistas por las rutinas de IPC. La IPC provee un mecanismo que
permite a los procesos comunicarse y sincronizarse entre sí, normalmente a
través de un sistema de bajo nivel de paso de mensajes que ofrece la red subyacente.
La comunicación se
establece siguiendo una serie de reglas (protocolos de comunicación). Los
protocolos desarrollados para internet son los mayormente usados: IP (capa de
red), protocolo de
control de transmisión (capa de
transporte) y protocolo de transferencia de archivos, protocolo de
transferencia de hipertexto (capa de
aplicación).
Los procesos pueden
estar ejecutándose en una o más computadoras conectadas a una red. Las técnicas
de IPC están divididas dentro de métodos para: paso de mensajes,
sincronización, memoria compartida y llamadas de procedimientos remotos (RPC).
El método de IPC usado puede variar dependiendo del ancho de banda y latencia
(el tiempo desde el pedido de información y el comienzo del envío de la misma)
de la comunicación entre procesos, y del tipo de datos que están siendo
comunicados. En muchos casos, los procesos se reúnen para realizar tareas en
conjunto, a este tipo de relación se le llama procesos cooperativos. Para
lograr la comunicación, los procesos deben sincronizarse, de no ser así pueden
ocurrir problemas no deseados.
La sincronización es la
transmisión y recepción de señales que tiene por objeto llevar a cabo el
trabajo de un grupo de procesos cooperativos. Es la coordinación y cooperación
de un conjunto de procesos para asegurar la comparación de recursos de cómputo.
La sincronización entre procesos es necesaria para prevenir y/o corregir
errores de sincronización debidos al acceso concurrente a recursos compartidos,
tales como estructuras de datos o dispositivos de E/S, de procesos
contendientes.
La sincronización también permite intercambiar señales de
tiempo (ARRANQUE/PARADA) entre procesos cooperantes para garantizar las
relaciones específicas de precedencia impuestas por el problema que se
resuelve. Sin una sincronización adecuada entre procesos, la actualización de
variables compartidas puede inducir a errores de tiempo relacionados con la
concurrencia que son con frecuencia difíciles de depurar. Una de las causas
principales de este problema es que procesos concurrentes puedan observar
valores temporalmente inconsistentes de una variable compartida mientras se
actualizan. Una aproximación para resolver este problema es realizar
actualizaciones de variables compartidas de manera mutuamente exclusiva. Se
pueden mejorar permitiendo que a lo más un proceso entre a la vez en la sección
crítica de código en la que se actualiza una variable compartida o estructura
de datos en particular.
Para que los procesos
puedan sincronizarse es necesario disponer de servicios que permitan bloquear o
suspender bajo determinadas circunstancias la ejecución de un proceso. Los
principales mecanismos de sincronización que ofrecen los sistemas operativos
son:
- Señales
- Tuberías
- Semáforos
- Mutex y variables condicionales
- Paso de mensajes