Instituto Tecnológico de Las Américas.
(ITLA)
Seguridad Informática
Asignatura
Sistemas operativos (6)
Alumno
Jesús Leonardo De la cruz cruz
Matricula
2016-4046
Profesor
José Doñe
Trabajo:
Sincronización entre procesos
Fecha:
22 de febrero 2017
1
Índice
Introducción--------------------------------------------------------------------------------Pág.3
Sincronización entre procesos---------------------------------------------------Pág.4
Comunicación entre procesos-----------------------------------------------------Pág.4-7
Mecanismos de comunicación-----------------------------------------------------Pág.7-12
Problemas clásicos entre la comunicación entre procesos---------------Pág.12-15
Conclusión---------------------------------------------------------------------------Pág.16
Bibliografía----------------------------------------------------------------------------Pág.17
2
Introducción
En este trabajo vamos a hablar sobre la sincronización entre
procesos, la cual es una de las funciones básicas de los sistemas
operativos, ya que tiene la característica de comunicarse entre si.
En este capitulo vamos a tratar los diferentes temas: La
comunicación entre procesos, los diferentes mecanismos de
sincronización (Semáforos, monitores, regiones críticas y secciones
críticas), los tipos de sincronización, además veremos los clásicos
problemas sobre la sincronización entre procesos.
Además, en este capitulo tenemos que concentrarnos en los
diferentes porque es esencial dominarlos para lleva a cabo esta
carrera. Veremos diferentes algoritmos los cuales nos describen
gráficamente la comunicación y sincronización de los procesos
3
Sincronización entre procesos
Comunicación entre procesos.
La comunicación entre procesos (comúnmente IPC, del inglés Inter-Process
Communication) 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 procediemientos 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. El sistema operativo provee mínimamente dos primitivas,
enviar y recibir, normalmente llamadas send y receive. Asimismo, debe
implementarse un enlace de comunicación entre los procesos de la
comunicación.
4
Este enlace puede ser unidireccional o multidireccional según permita la
comunicación en solo uno o en varios sentidos.
Tipos de comunicación.
La comunicación puede ser:
Síncrona o asíncrona
Persistente (persistent) o momentánea (transient)
Directa o indirecta
Simétrica o asimétrica
Con uso de buffers explícito o automático
Envío por copia del mensaje o por referencia
Mensajes de tamaño fijo o variable
Síncrona
Quien envía permanece bloqueado esperando a que llegue una respuesta del
receptor antes de realizar cualquier otro ejercicio.
Asíncrona
Quien envía
continúa con su
ejecución
inmediatamente
5
después de enviar el mensaje al receptor.
Persistente
El receptor no tiene que estar operativo al mismo tiempo que se realiza la
comunicación, el mensaje se almacena tanto tiempo como sea necesario para
poder ser entregado (Ej.: e-Mail).
Momentánea (transient)
El mensaje se descarta si el receptor no está operativo al tiempo que se realiza
la comunicación. Por lo tanto no será entregado.
Directa
Las primitivas enviar y recibir explicitan el nombre del proceso con el que se
comunican. Ejemplo:
enviar (mensaje, A) envía un mensaje al proceso A
Es decir se debe especificar cual va a ser el proceso fuente y cual va a ser el
proceso Destino.
Las operaciones básicas Send y Receive se definen de la siguiente manera:
Send (P, mensaje); envía un mensaje al proceso P (P es el proceso destino).
Receive (Q, mensaje); espera la recepción de un mensaje por parte del
proceso Q (Q es el proceso fuente).
Nota: Receive puede esperar de un proceso cualquiera, un mensaje, pero el
Send sí debe especificar a quién va dirigido y cuál es el mensaje.
Indirecta
La comunicación Indirecta: Es aquella donde la comunicación está basada en
una herramienta o instrumento ya que el emisor y el receptor están a distancia.
Simétrica
Todos los procesos pueden enviar o recibir. También llamada bidireccional
para el caso de dos procesos. Es una comunicación equilibrada donde tanto
emisor como receptor reciben la misma información.
Asimétrica
Un proceso puede enviar, los demás procesos solo reciben. También llamada
unidireccional. Suele usarse para hospedar servidores en Internet.ç
Uso de buffers automático
El transmisor se bloquea hasta que el receptor recibe el mensaje (capacidad
cero).
Comunicación entre procesos Linux
Señales
6
El mecanismo estándar para informar a un proceso que ha ocurrido un evento
es la señal. Se pueden enviar señales de un proceso a otro pero sin enviar
información. Las señales no necesitan ser generadas por otro proceso, también
puede ser generada por el kernel.
Linux también implementa un mecanismo de semáforos. Un proceso puede
esperar un semáforo tan fácilmente como espera una señal.
Paso de datos entre procesos
El mecanismo de tubería (pipe) estándar permite a un proceso hijo heredar un
canal de comunicación con su padre; los datos que se escriben en un extremo
de la tubería se leen en el otro. También define un conjunto de servicios para
trabajo en red que pueden enviar flujos de datos tanto a procesos locales como
remotos.
Hay otro método que es la memoria compartida que ofrece una forma
extremadamente rápida de comunicar cantidades grandes o pequeñas de
datos; cualquier dato escrito por un proceso en una región de memoria
compartida puede ser leído por cualquier otro proceso que haya mapeado
dicha region en su espacio de direcciones.
Freedesktop
Para comunicación entre aplicaciones gráficas existe D-Bus, usado por
GNOME y KDE entre otros. Permite fácilmente comunicar unas aplicaciones
con otras o controlar cualquier elemento de una interfaz gráfica desde consola
a con un programa hecho al efecto.
Mecanismos de sincronización
Semaforos
Un semáforo es una variable especial (o tipo abstracto de datos) que constituye
el método clásico para restringir o permitir el acceso a recursos compartidos
(por ejemplo, un recurso de almacenamiento del sistema o variables del código
fuente) en un entorno de multiprocesamiento (en el que se ejecutarán varios
procesos concurrentemente). Fueron inventados por Edsger Dijkstra en 1965 y
se usaron por primera vez en el sistema operativo THEOS
Estas instrucciones pueden modificarse para evitar la espera activa, haciendo
que la operación P duerma al mismo proceso que la ejecuta si no puede
decrementar el valor, mientras que la operación V despierta a un proceso que
no es quien la ejecuta. En un pseudolenguaje más entendible, la operación P
suele denominarse "wait" o "espera" y la operación V "signal" o "señal".
El porqué de los nombres de estas funciones, V y P, tiene su origen en el
idioma holandés. "Verhogen" significa incrementar y "Proberen" probar, aunque
Dijkstra usó la palabra inventada prolaag [1], que es una combinación de
probeer te verlagen (intentar decrementar). El valor del semáforo es el número
7
de unidades del recurso que están disponibles (si sólo hay un recurso, se utiliza
un "semáforo binario" cuyo valor inicial es 1).
La verificación y modificación del valor, así como la posibilidad de irse a dormir
(bloquerse) se realiza en conjunto, como una sola e indivisible acción atómica.
El sistema operativo garantiza que al iniciar una operación con un semáforo,
ningún otro proceso puede tener acceso al semáforo hasta que la operación
termine o se bloquee. Esta atomicidad es absolutamente esencial para resolver
los problemas de sincronización y evitar condiciones de competencia.
Si hay n recursos, se inicializará el semáforo al número n. Así, cada proceso, al
ir solicitando un recurso, verificará que el valor del semáforo sea mayor de 0; si
es así es que existen recursos libres, seguidamente acaparará el recurso y
decrementará el valor del semáforo.
Cuando el semáforo alcance el valor 0, significará que todos los recursos están
siendo utilizados, y los procesos que quieran solicitar un recurso deberán
esperar a que el semáforo sea positivo, esto es: alguno de los procesos que
están usando los recursos habrá terminado con él e incrementará el semáforo
con un signal o V(s).
Inicia se utiliza para inicializar el semáforo antes de que se hagan peticiones
sobre él, y toma por argumento a un entero. La operación P cuando no hay un
recurso disponible, detiene la ejecución quedando en espera activa (o
durmiendo) hasta que el valor del semáforo sea positivo, en cuyo caso lo
reclama inmediatamente decrementándolo. V es la operación inversa: hace
8
disponible un recurso después de que el proceso ha terminado de usarlo. Las
operaciones P y V han de ser indivisibles (o atómicas), lo que quiere decir que
cada una de las operaciones no debe ser interrumpida en medio de su
ejecución.
La operación V es denominada a veces subir el semáforo (up) y la operación P
se conoce también como bajar el semáforo (down), y también son llamadas
signal y wait o soltar y tomar.
Para evitar la
espera activa,
un semáforo
puede tener
asociada una
cola de
procesos
(normalmente
una cola FIFO).
Si un proceso
efectúa una
operación P en
un semáforo
que tiene valor
cero, el proceso
es detenido y añadido a la cola del semáforo. Cuando otro proceso incrementa
el semáforo mediante la operación V y hay procesos en la cola asociada, se
extrae uno de ellos (el primero que entró en una cola FIFO) y se reanuda su
ejecución.
Aplicaciones
Los semáforos se emplean para permitir el acceso a diferentes partes de
programas (llamados secciones críticas) donde se manipulan variables o
recursos que deben ser accedidos de forma especial. Según el valor con que
son inicializados se permiten a más o menos procesos utilizar el recurso de
forma simultánea.
Un tipo simple de semáforo es el binario, que puede tomar solamente los
valores 0 y 1. Se inicializan en 1 y son usados cuando sólo un proceso puede
acceder a un recurso a la vez. Son esencialmente lo mismo que los mutex.
Cuando el recurso está disponible, un proceso accede y decrementa el valor
del semáforo con la operación P. El valor queda entonces en 0, lo que hace
que si otro proceso intenta decrementarlo tenga que esperar. Cuando el
proceso que decrementó el semáforo realiza una operación V, algún proceso
que estaba esperando comienza a utilizar el recurso.
Para hacer que dos procesos se ejecuten en una secuencia predeterminada
puede usarse un semáforo inicializado en 0. El proceso que debe ejecutar
primero en la secuencia realiza la operación V sobre el semáforo antes del
código que debe ser ejecutado después del otro proceso. Éste ejecuta la
9
operación P. Si el segundo proceso en la secuencia es programado para
ejecutar antes que el otro, al hacer P dormirá hasta que el primer proceso de la
secuencia pase por su operación V. Este modo de uso se denomina señalación
(signaling), y se usa para que un proceso o hilo de ejecución le haga saber a
otro que algo ha sucedido.
Monitor
En la programación paralela, los monitores son objetos destinados a ser
usados sin peligro por más de un hilo de ejecución. La característica que
principalmente los define es que sus métodos son ejecutados con exclusión
mutua. Lo que significa, que en cada momento en el tiempo, un hilo como
máximo puede estar ejecutando cualquiera de sus métodos. Esta exclusión
mutua simplifica el razonamiento de implementar monitores en lugar de código
a ser ejecutado en paralelo.
En el estudio y uso de los semáforos se puede ver que las llamadas a las
funciones necesarias para utilizarlos quedan repartidas en el código del
programa, haciendo difícil corregir errores y asegurar el buen funcionamiento
de los algoritmos. Para evitar estos inconvenientes se desarrollaron los
monitores. El concepto de monitor fue definido por primera vez por Charles
Antony Richard Hoare en un artículo del año 1974. La estructura de los
monitores se ha implementado en varios lenguajes de programación, incluido
Pascal concurrente, Modula-2, Modula-3 y Java, y como biblioteca de
programas.
Un monitor tiene cuatro componentes: inicialización, datos privados, métodos
del monitor y cola de entrada.
Inicialización: contiene el código a ser ejecutado cuando el monitor es creado
Datos privados: contiene los procedimientos privados, que sólo pueden ser
usados desde dentro del monitor y no son visibles desde fuera
Métodos del monitor: son los procedimientos que pueden ser llamados desde
fuera del monitor.
Cola de entrada: contiene a los hilos que han llamado a algún método del
monitor pero no han podido adquirir permiso para ejecutarlos aún.
Antes se dijo que una llamada a la función cond_signal con una variable de
condición hacía que un proceso que estaba esperando por esa condición
reanudara su ejecución. Nótese que el thread que reanuda su ejecución
necesitará obtener nuevamente el lock del monitor. Surgen las siguientes
preguntas: ¿Qué sucede con el thread que hizo el cond_signal? ¿Pierde el lock
para dárselo al thread que esperaba? ¿Qué thread continúa con su ejecución?
Cualquier solución debe garantizar la exclusión mutua. Según quién continúa
con la ejecución, se diferencian dos tipos de monitores: Hoare y Mesa.
Tipo Hoare
En la definición original de Hoare, el thread que ejecuta cond_signal le cede el
monitor al thread que esperaba. El monitor toma entonces el lock y se lo
10
entrega al thread durmiente, que reanuda la ejecución. Más tarde cuando el
monitor quede libre nuevamente el thread que cedió el lock volverá a ejecutar.
Ventajas:
El thread que reanuda la ejecución puede hacerlo inmediatamente sin fijarse si
la condición se cumple, porque desde que se ejecutó cond_signal hasta que
llegó su turno de ejecutar ningún proceso puede cambiarla.
El thread despertado ya estaba esperando desde antes, por lo que podría
suponerse que es más urgente ejecutarlo a seguir con el proceso despertante.
Desventajas:
Si el proceso que ejecuta cond_signal no terminó con su ejecución se
necesitarán dos cambios de contexto para que vuelva a tomar el lock del
monitor.
Al despertar a un thread que espera en una variable de condición, se debe
asegurar que reanude su ejecución inmediatamente. De otra forma, algún otro
thread podría cambiar la condición. Esto implica que la planificación debe ser
muy fiable, y dificulta la implementación.
Tipo Mesa
Butler W. Lampson y
David D. Redell en
1980 desarrollaron una
definición diferente de
monitores para el
lenguaje Mesa que lidia
con las desventajas de
los monitores de tipo
Hoare y añade algunas
características.
En los monitores de
Lampson y Redell el
thread que ejecuta
cond_signal sobre una
variable de condición continúa con su ejecución dentro del monitor. Si hay otro
thread esperando en esa variable de condición, se lo despierta y deja como
listo. Podrá intentar entrar el monitor cuando éste quede libre, aunque puede
suceder que otro thread logre entrar antes. Este nuevo thread puede cambiar la
condición por la cual el primer thread estaba durmiendo. Cuando reanude la
ejecución el durmiente, debería verificar que la condición efectivamente es la
que necesita para seguir ejecutando. En el proceso que durmió, por lo tanto, es
necesario cambiar la instrucción if por while, para que al despertar compruebe
nuevamente la condición, y de no ser cierta vuelva a llamar a cond_wait.
Además de las dos primitivas cond_wait(c) y cond_signal(c), los monitores de
Lampson y Redell poseen la función cond_broadcast(c), que notifica a los
threads que están esperando en la variable de condición c y los pone en estado
11
listo. Al entrar al monitor, cada thread verificará la condición por la que estaban
detenidos, al igual que antes.
Sección critica
Se denomina sección crítica, en programación concurrente, 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.
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.
Sólo un proceso puede estar en una sección crítica a la vez.
El método más común para evitar que dos procesos accedan al mismo tiempo
a un recurso es el de la exclusión mutua.
12
Problemas clásicos entre la comunicación entre procesos.
Problema de la sección crítica:
Se denomina sección crítica, enprogramaciónconcurrente,a la porción
decódigode un programa de computador en la cual se accede aun recurso
compartido (estructura de datos o dispositivo) que no debe ser accedido
pormás de un hilo en ejecución. La sección crítica por lo general termina en un
tiempodeterminado y el hilo, proceso o tarea sólo tendrá que esperar un
período determinadode tiempo para entrar. Se necesita un mecanismo de
sincronización en la entrada y salidade la sección crítica para asegurar la
utilización en exclusiva del recurso, por ejemplo unsemáforo. El acceso
concurrente se controla teniendo cuidado de las variables que se
modificandentro y fuera de la sección crítica. La sección crítica se utiliza por lo
general cuando unprogramamultihil7-oactualiza múltiples variables sin un hilo
de ejecución separado quelleve los cambios conflictivos a esos datos. Una
situación similar, la sección crítica puedeser utilizada para asegurarse de que
un recurso compartido, por ejemplo, una impresora,puede ser accedida por un
solo proceso a la [Link] manera en cómo se implementan las secciones puede
variar dependiendo de losdiversos sistemas operativos.Sólo unprocesopuede
estar en una sección crítica a la vez.
Problema productor-consumidor:
Consiste en el acceso concurrente por parte deprocesos productores y
procesos consumidores sobre un recurso común que resulta serun buffer de
elementos. Los productores tratan de introducir elementos en el buffer deuno
en uno, y los consumidores tratan de extraer elementos de uno en [Link]
asegurar la consistencia de la información almacenada en el buffer, el acceso
de losproductores y consumidores debe hacerse en exclusión mutua.
Adicionalmente, el bufferes de capacidad limitada, de modo que el acceso por
parte de un productor paraintroducir un elemento en el buffer lleno debe
provocar la detención del procesoproductor. Lo mismo sucede para un
consumidor que intente extraer un elemento delbuffer vací[Link] de
lectores-escritores: Hay un objeto de datos(fichero de texto) que es utilizadopor
varios procesos, unos leen y otro que [Link] puede utilizar el recurso un
proceso y solo uno, es decir, o bien un proceso estaráescribiendo o bien
leyendo, pero nunca ocurrirá simultáneamente (teniendo en cuentaque si no lo
esta utilizando nadie, tendrá preferencia el escritor ante el lector
El problema de la cena de los filósofos
En 1965 Dijkstra planteó y resolvió un problema de sincronización llamado el
problema de la cena de los filósofos, que se puede enunciar como sigue. Cinco
filósofos se sientan a la mesa, cada uno con un plato de espaghetti. El
espaghetti es tan escurridizo que un filósofo necesita dos tenedores para
comerlo. Entre cada dos platos hay un tenedor. En imagen se muestra la mesa.
13
Los filósofos se disponen a comer
La vida de un filósofo consta de periodos alternos de comer y pensar. Cuando
un filósofo tiene hambre, intenta obtener un tenedor para su mano derecha, y
otro para su mano izquierda, cogiendo uno a la vez y en cualquier orden. Si
logra obtener los dos tenedores, come un rato y después deja los tenedores y
continúa pensando. La pregunta clave es: puede el lector escribir un programa
para cada filósofo que permita comer equitativamente a los filósofos y no se
interbloquee?
El problema de los
lectores y los
escritores
El problema de la
cena de los filósofos
es útil para modelar
procesos que
compiten por el
acceso exclusivo a
un número limitado
de recursos, como
una unidad de cinta u
otro dispositivo de
E/S. Otro problema
famoso es el de los
lectores y escritores
(Courtois et al.,
1971), que modela el
acceso a una base
de datos. Supóngase
una base de datos,
con muchos procesos que compiten por leer y escribir en ella. Se puede
permitir que varios procesos lean de la base de datos al mismo tiempo, pero si
uno de los procesos está escribiendo (es decir, modificando) la base de datos,
ninguno de los demás debería tener acceso a ésta, ni siquiera los lectores.
En esta solución, el primer lector que obtiene el acceso a la base de datos
realiza un wait sobre el semáforo bd. Los lectores siguientes sólo incrementan
un contador, nl. Al salir los lectores, éstos decrementan el contador, y el último
en salir realiza un signal sobre el semáforo, lo que permite entrar a un escritor
bloqueado, si existe.
Una hipótesis implícita en esta solución es que los lectores tienen prioridad
sobre los escritores. Si surge un escritor mientras varios lectores se encuentran
en la base de datos el escritor debe esperar. Pero si aparecen nuevos lectores,
y queda al menos un lector accediendo a la base de datos, el escritor deberá
esperar hasta que no haya más lectores interesados en la base de datos.
14
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.
15
Conclusión
En este trabajo tratamos la sincronización entre los procesos, con el
objetivo de aprender los diferentes tipos de sincronización que
pueden ocurrir en un sistema operativo.
Vimos los tipos de sincronizaciones como: asíncrona, síncrona,
directa, indirecta, simétrica y asimétrica, con sus ejemplificaciones
Además tratamos los diferentes mecanismos de comunicación
como lo son: semáforos, monitores, sección y región crítica.
Vimos los diferentes problemas entre la comunicación de procesos
como lo son: el problema de la cena de los filósofos, problema
cliente- servidor, problema productor-consumidor, con sus
diferentes diagramas de representación.
16
Bibliografía.
- [Link]
- [Link]
-[Link]
. [Link]
- [Link]
17