Resumen Teórico Programación Concurrente
Resumen Teórico Programación Concurrente
1
Solución como un problema de exclusión mutua 20
Solución como un problema de exclusión mutua 20
Si en el problema solo se acepta 1 escritor o un 1 lector en la base de datos ¿Tenemos un
problema de exclusión mutua selectiva? 20
Técnica Passing the Baton 20
Técnica Passing the Condition 21
Relación y diferencias con Passing the Condition 21
Alocación de Recursos y Scheduling 21
Alocación Shortest-Job-Next (SJN) 22
Monitores 22
Notación de los Monitores 22
Implementación de la Sincronización por Condición 23
Protocolos de Sincronización - Disciplinas de Sincronización 23
Signal and Continue 23
Signal and Wait 23
Diferencias 24
Problemas Concurrentes y Técnicas con Monitores 24
Alocación SJN - Wait con Prioridad y Variables Condición Privadas 24
Problema del Peluquero Dormilón - Rendezvous 24
Problema de Scheduling de Disco 25
Solución con Monitor Separado 26
Solución con Monitor Intermedio 26
Conceptos Generales del Procesamiento Distribuido 26
Dualidad entre los mecanismos de pasaje de mensajes y monitores 26
Características de los Canales 27
Canal Mailbox 27
Canal Input port 27
Canal Link 27
Relación entre mecanismos de sincronización 27
Pasaje de Mensajes Asincrónicos 27
Problemas Concurrentes y Técnicas con PMA 28
Productores y Consumidores - Filtros 28
Filtros 28
Solución con Red de Ordenación 28
Clientes y Servidores 29
Continuidad Conversacional 30
Pares que interactúan 30
Solución Simétrica 31
Solución Centralizada 31
Solución Anillo 31
Pasaje de Mensajes Sincrónicos 31
CSP - Lenguaje para Pasaje de Mensajes Sincrónicos 32
Comunicación guardada 32
Resultados de la evaluación de una guarda 32
Ejecución 32
Ejemplo - Criba de Eratóstenes 💀 33
2
Paradigmas de Interacción entre Procesos 34
Paradigma Master/Worker 34
Paradigma Heartbeat 34
Topología de una red 34
Paradigma Pipeline 34
Paradigma Probe/Echo 34
Paradigma Broadcast 35
Paradigma Token Passing 35
Paradigma Servidores Replicados 35
RPC y Rendezvous 35
Similitudes 36
Diferencias 36
RPC (Remote Procedure Call) 36
Enfoques para proveer sincronización 37
Rendezvous 37
¿Qué elemento de la forma general de Rendezvous no se encuentra en ADA? 37
ADA - Lenguaje con Rendezvous 37
Comunicación Guardada 37
Thread 38
POSIX Threads - Pthreads 38
Funciones Básicas de Pthreads 38
Sincronización por Exclusión Mutua 38
Funciones 39
Sincronización por Condición 39
Funciones 39
Attribute Object 40
Semáforos 40
Monitores 41
Librerías para manejo de Pasaje de Mensajes 41
MPI - Message Passing Interface 41
Funciones 41
Comunicadores 42
Clasificación de Arquitecturas Paralelas 42
Arquitecturas clasificadas por Mecanismos de Control 43
SISD - Single Instruction Single Data 43
SIMD - Single Instruction Multiple Data 44
MISD - Multiple Instruction Single Data 44
MIMD - Multiple Instruction Multiple Data 44
Diseño de Algoritmos Paralelos 44
Descomposición de Datos 44
Descomposición Funcional 45
Aglomeración 45
Objetivos que guían las decisiones de Aglomeración y Replicación 45
Características de las Tareas 45
Mapeo de Procesos a Procesadores 45
Criterio para el Mapeo de Tareas a Procesadores 46
3
Métrica de Speedup 46
Métrica de Eficiencia 46
Programa Paralelizado 46
Ley de Amdahl 47
4
○ Hay un no determinismo implícito en los procesos concurrentes. Esto significa que
dos ejecuciones del mismo programa no necesariamente son idénticas.
● Mayor complejidad en los compiladores y sistemas operativos asociados.
● Mayor costo de los ambientes y herramientas de Ingeniería de Software de sistemas
concurrentes.
● La paralelización de algoritmos secuenciales no es un proceso directo. Para obtener una real
mejora de performance, se requiere adaptar el software concurrente al hardware paralelo.
5
instrucciones, tampoco se puede determinar si dará la misma salida. Sólo se puede
asegurar un orden Parcial.
● Interferencia:
○ Se da cuando un proceso toma una acción que invalida alguna suposición hecha por
otro proceso.
○ La Interferencia se da por la realización de asignaciones en un proceso a variables
compartidas que pueden afectar el comportamiento o invalidar un supuesto
realizado por otro proceso.
○ Se puede evitar usando mecanismo de sincronización y asegurando propiedades
como la de ASV “A lo Sumo una Vez”.
● Comunicación:
○ Indica el modo en que se organizan y transmiten datos entre tareas concurrentes.
Esta organización requiere especificar protocolos para controlar el progreso y la
corrección.
6
○ No se puede operar simultáneamente sobre la memoria compartida, es decir, es
necesario usar algún mecanismo como los semáforos que permita bloquear y liberar
el acceso a la memoria.
○ Requiere el uso de exclusión mutua o sincronización por condición.
● Memoria Distribuida:
○ Los procesos se comunican a través de mensajes que llevan datos, es necesario
establecer un canal lógico o físico para transmitir información entre procesos.
○ El pasaje de mensajes puede ser sincrónico o asincrónico y es independiente de la
arquitectura.
○ Requiere del intercambio de mensajes evitando así problemas de inconsistencia.
● En un programa concurrente pueden estar presentes más de un mecanismo de
sincronización a la vez.
● En términos de facilidad de programación es mucho más fácil programar con memoria
distribuida porque el programador puede olvidarse de la exclusión mutua.
Deadlock
● Situación en la que dos o más procesos o hilos en un sistema concurrente quedan atrapados
en un estado en el que ninguno puede continuar su ejecución debido a que cada uno está
esperando a que el otro libere un recurso que necesita.
● Condiciones necesarias y suficientes para que ocurra el deadlock:
○ Recursos reusables serialmente:
■ Los procesos comparten recursos que pueden usar con exclusión mutua.
○ Adquisición Incremental:
■ Los procesos mantienen los recursos que poseen mientras esperan adquirir
recursos adicionales.
○ No-preemption:
■ Una vez que un proceso adquiere recursos, estos no pueden ser retirados de
manera forzada sino que sólo son liberados voluntariamente.
○ Espera cíclica:
■ Existe una cadena circular de procesos tal que cada uno tiene un recurso que
su sucesor en el ciclo está esperando adquirir.
● Con que evitemos que se cumpla una de estas condiciones nos alcanza para que el
deadlock no exista.
Granularidad
● Es la relación que existe entre el procesamiento y la comunicación.
● Arquitectura de grano fino:
○ Arquitectura de muchos procesadores con poca capacidad de procesamiento.
○ Esta arquitectura es mejor para programas que requieran mucha comunicación.
● Arquitectura de grano grueso:
○ Arquitectura de pocos procesadores con mucha capacidad de procesamiento.
○ Esta arquitectura es mejor para programas que requieran pocos procesos que
realizan mucho procesamiento y poca comunicación.
7
○ Acciones que hacen una transformación de estado indivisible, es decir, cualquier
estado intermedio que podría existir en la implementación de la acción no debe ser
visible para los otros procesos.
● Atomicidad de Grano Fino:
○ Acciones que son implementadas directamente por el hardware sobre el que ejecuta
el programa concurrente.
Sentencia Await
● Acción atómica de grano grueso, la cual es una secuencia de acciones atómicas de grano
fino que aparecen como indivisibles.
● Puede ser usada para especificar acciones atómicas arbitrarias de grano grueso. Esto la hace
conveniente para expresar sincronización.
● Podemos especificar sincronización a partir de usar la sentencia de la forma < 𝑎𝑤𝑎𝑖𝑡 (𝐵) 𝑆; >
○ B es la condición de demora.
○ S es una secuencia de sentencias que se garantiza que termina.
○ La sentencia se encierra entre <> para indicar que es ejecutada como una acción
atómica.
○ En particular, se garantiza que B es true cuando comienza la ejecución de S, y ningún
estado interno de S es visible para los otros procesos.
● Podemos hacer solo exclusión mutua con < 𝑆 >.
● Podemos hacer solo sincronización por condición con < 𝑎𝑤𝑎𝑖𝑡 (𝐵) >.
8
1. “e” contiene a los umo una referencia crítica y “x” no es referenciada por otro proceso,
o
2. “e” no contiene referencias críticas, en cuyo caso “x” puede ser leída por otro
proceso.
● Una expresión que no está en una sentencia de asignación satisface la propiedad de “A lo
sumo una vez” si no contiene más de una referencia crítica.
● Básicamente a lo sumo una variable compartida y a lo sumo se referencia una vez.
● Si una sentencia de asignación cumple la propiedad ASV, entonces su ejecución parece
atómica, pues la variable compartida será leída o escrita sólo una vez.
9
○ Total Correctness es la combinación de Partial Correctness y Terminación.
10
■ El estado “malo" es cuando un proceso queda excluido repetidamente de su
sección crítica.
Spin Locks
● Tiene como objetivo hacer atómico el await de grano grueso, para esto hacemos uso de una
instrucción especial que puede usarse para implementar las acciones atómicas
condicionales, en este caso usamos Test-and-Set pero existen otras como Fetch-and-Add o
Compare-and-Swap.
● Test-and-Set:
○ Toma una variable “lock” booleana como argumento. Esta variable representa el
estado del recurso compartido. Si "lock" es falso, el recurso está disponible. Si "lock"
es verdadero, el recurso está siendo utilizado por otro proceso.
○ Atómicamente, TS guarda el valor inicial de “lock” en una variable temporal:
■ Establece “lock” en verdadero, indicando que el recurso ya no está
disponible.
■ Devuelve el valor original de “lock”.
○ El proceso que llama a TS analiza el valor devuelto:
■ Si es falso, significa que el proceso ha adquirido el recurso y puede entrar a la
Sección Crítica.
■ Si es verdadero, significa que otro proceso ya está utilizando el recurso. El
proceso que llamó a TS debe esperar y volver a intentar adquirir el recurso.
● Desventajas de este tipo de solución:
○ Las soluciones de este estilo no controlan el orden de los procesos demorados.
○ Cumple las 4 propiedades del problema si el scheduling es fuertemente fair.
○ En multiprocesadores puede llevar a una baja performance si varios procesos están
compitiendo por el acceso a una Sección Crítica, causando Memory Contention.
○ Genera busy-waiting.
11
Algoritmo Tie-Breaker
● Protocolo de Sección Crítica que requiere solo scheduling incondicionalmente fair para
satisfacer la propiedad de eventual entrada.
● No requiere instrucciones especiales del tipo Test-and-Set.
● El algoritmo es mucho más complejo que la solución con Spin Locks.
● Usa una variable por cada proceso para indicar que el proceso comenzó a ejecutar su
protocolo de entrada a la sección crítica, y una variable adicional para romper empates,
indicando qué proceso fue el último en comenzar dicha entrada, esta última variable es
compartida y de acceso protegido.
● El algoritmo tie-breaker de N-procesos es costoso en tiempo y bastante complejo y difícil de
entender.
12
Tie-Breaker para N procesos
Algoritmo Ticket
● Solución para N procesos más fácil de entender que la solución de N procesos del algoritmo
Tie-Breaker.
● En esta solución se reparten números y se espera turno:
○ Los clientes toman un número mayor que el de cualquier otro que espera ser
atendido; luego esperan hasta que todos los clientes con un número más chico sean
atendidos.
● La ausencia de deadlock y de demora innecesaria resultan de que los valores de turno son
únicos. Con scheduling débilmente fair se asegura eventual entrada.
● El problema de este algoritmo es que los valores del próximo número y del turno son
ilimitados, si el algoritmo corre un tiempo largo se puede alcanzar un overflow.
○ Para tratar esto podemos resetear los contadores cuando notamos que los valores
son muy grandes.
● Hace uso de la instrucción especial Fetch-and-Add, sin el uso de esta instrucción se debe
simular con una Sección Crítica y la solución puede no ser fair.
● Fetch-and-Add:
○ Esta operación hace 2 acciones atómicas:
■ Lee el valor actual de una variable.
■ Incrementa esa variable por una cantidad específica.
○ La operación devuelve el valor original de la variables (antes de incrementar) y
asegura que la actualización del valor se haga de forma segura.
13
Algoritmo Bakery
● Algoritmo del tipo de ticket que es fair y no requiere instrucciones de máquina especiales.
● El algoritmo es más complejo que el ticket, pero ilustra una manera de romper empates
cuando dos procesos obtienen el mismo número.
● No requiere un contador global próximo que se “entrega” a cada proceso al llegar a la Sección
Crítica.
● Cada proceso que trata de ingresar recorre los números de los demás y se autoasigna uno
mayor. Luego espera a que su número sea el menor de los que esperan.
● Los procesos se chequean entre ellos y no contra un global.
● El algoritmo asegura entrada eventual si el scheduling es débilmente fair.
14
● Como muchos problemas pueden ser resueltos con algoritmos iterativos paralelos en los que
cada iteración depende de los resultados de la iteración previa, es necesario proveer
sincronización entre los procesos al final de cada iteración, para realizar esto se utilizan las
barreras.
15
● Desventajas:
○ Los procesos no son simétricos ya que cada uno cumple diferentes roles, por lo que
los nodos centrales realizarán más trabajo que los nodos hoja y la raíz.
Barrera Simétrica
● Conjunto de barreras entre pares de procesos que utilizan sincronización barrier. En cada
etapa los pares de procesos que interactúan van cambiando dependiendo de algún criterio
establecido.
16
Semáforos
● Herramienta que nos permite realizar sincronización entre procesos concurrentes. Es una
instancia de un tipo de datos abstracto con sólo 2 operaciones atómicas P y V. Internamente
el valor de un semáforo es un entero no negativo:
○ V:
■ Señala la ocurrencia de un evento incrementando de forma atómica el valor
interno del semáforo.
○ P:
■ Se usa para demorar un proceso hasta que ocurra un evento decrementando
de forma atómica el valor interno del semáforo.
● Permiten realizar sincronización por exclusión mutua (proteger secciones críticas) y por
condición.
Semáforo Binario
● P(b): <await (b > 0) b = b + 1;>
● V(b): <await (b < 1) b = b + 1;>
17
○ Los semáforos binarios (en nuestro caso semáforos generales que simulan a los
binarios) b1, b2, b3, b…, bN forman un SBS en un programa si se cumple que la suma
de todos los semáforos es mayor o igual que 0 y menor o igual que 1, es decir, es
binaria.
○ Se puede ver como un semáforo binario que fue dividido en n partes.
○ Tienen una implementación específica para la exclusión mutua (problema de la
sección crítica)
■ En general la ejecución de los procesos inicia con un P sobre un semáforo y
termina con un V sobre otro de ellos. Esto permite que se genere una
alternancia entre procesos para ejecutar la sección crítica.
● Ejemplo: Buffer unitario compartido con múltiples productores y consumidores. Dos
operaciones: depositar y retirar que deben alternarse.
18
Con más de un productor y un consumidor, las operaciones depositar y retirar son secciones críticas
y se deben ejecutar con exclusión mutua.
Si en lugar de 5 filósofos fueran 3 ¿El problema sigue siendo de exclusión mutua selectiva?
● En el caso de que fueran 3 filósofos y no 5 como en la definición del problema general, no
sería de exclusión mutua selectiva ya que un proceso compite con todos los demás procesos
y no solo con un subconjunto de ellos, dado que el resto de los procesos son sus adyacentes.
19
○ Los filósofos le consultan a un solo coordinador o mozo para poder tomar los
cubiertos, en este caso, el mozo se los da si es que hay dos cubiertos disponibles sin
tener en cuenta vecinos.
● Para este caso el problema deja de ser de exclusión mutua selectiva ya que compiten entre
todos por acceder a los cubiertos.
20
○ Un semáforo “e” inicialmente en 1 que controla la entrada a la SC.
○ Un semáforo “bj” inicialmente en 0, asociado con cada condición de espera.
○ Por cada semáforo “bj” un contador “dj” inicializado en 0, que cuenta la cantidad de
procesos dormidos en el semáforo “bj” esperando que la condición se vuelva
verdadera.
○ El conjunto de los semáforos “e” y todos los “bj” forman un SBS.
● Traducción de las sentencias:
○ F1:
■ P(e);
Si;
SIGNAL;
○ F2:
■ P(e);
if (not Bi) {
dj = dj +1;
V(e);
P(bj);
}
Sj;
SIGNAL;
○ SIGNAL:
■ if (B1 and d1 > 0) {
d1 = d1 - 1;
V(b1)
}
[] ...
elif (Bn and dn > 0) {
dn = dn - 1;
V(bn );
}
else V(e);
21
Alocación de Recursos y Scheduling
● Problema: Decidir cuándo se le puede dar acceso a un recurso a un proceso en específico.
Este recurso puede ser un objeto, elemento, componente, SC, etc. que hace que el proceso se
demore al esperar adquirirlo.
● Definición del Problema: Procesos que compiten por el uso de unidades de recurso
compartido (cada unidad está libre o en uso)
○ El proceso tiene que hacer un request(parámetros) del/los recurso/s, usar el/los
recurso/s y por último un release(parámetros) del/los recurso/s.
● Podemos hacer uso de la técnica Passing the Baton
Monitores
● Módulos de programa con más estructura, y que pueden ser implementados tan
eficientemente como los semáforos.
● Es un Mecanismo de abstracción de datos que:
○ Encapsula las representaciones de los recursos.
○ Brinda un conjunto de operaciones que son los únicos medios para manipular esos
recursos.
● Contiene variables que almacenan el estado del recurso y procedimientos que implementan
las operaciones sobre él.
● Actúan de forma pasiva, es decir, estos únicamente se ejecutan cuando un proceso activo de
un programa concurrente invoca un procedure de un monitor.
22
● La comunicación y exclusión mutua se resuelve de forma implícita ya que se asegura que los
procedures que estén dentro de un mismo monitor no se ejecutan concurrentemente.
● La sincronización por condición se resuelve de forma explícita con el uso de variables
condición.
23
Signal and Continue
● El proceso que hace el signal(cv) despierta al proceso que estaba dormido pero sigue
haciendo uso del monitor hasta que termina de hacer uso del mismo o es dormido.
● El proceso que fue despertado tendrá que competir para volver a acceder al monitor.
Diferencias
● Signal and Continue
○ El proceso que hace el signal continua usando el monitor, y el proceso despertado
pasa a competir por acceder nuevamente al monitor para continuar con su ejecución
(en la instrucción que lógicamente le sigue al wait).
● Signal and wait
○ El proceso que hace el signal pasa a competir por acceder nuevamente al monitor,
mientras que el proceso despertado pasa a ejecutar dentro del monitor a partir de
instrucción que lógicamente le sigue al wait.
24
Problema del Peluquero Dormilón - Rendezvous
● Descripción:
○ Una ciudad tiene una peluquería con 2 puertas y unas pocas sillas. Los clientes
entran por una puerta y salen por la otra. Como el negocio es chico, a lo sumo un
cliente o el peluquero se pueden mover en él a la vez. El peluquero pasa su tiempo
atendiendo clientes, uno por vez. Cuando no hay ninguno, el peluquero duerme en su
silla. Cuando llega un cliente y encuentra que el peluquero está durmiendo, el cliente
lo despierta, se sienta en la silla del peluquero, y duerme mientras el peluquero le
corta el pelo. Si el peluquero está ocupado cuando llega un cliente, éste se va a
dormir en una de las otras sillas. Después de un corte de pelo, el peluquero abre la
puerta de salida para el cliente y la cierra cuando el cliente se va. Si hay clientes
esperando, el peluquero despierta a uno y espera que se siente. Sino, se vuelve a
dormir hasta que llegue un cliente.
● Tipos del proceso del problema → clientes y peluquero
● Monitor → administrador de la peluquería con tres procedures:
○ corte_de_pelo → llamado por los clientes, que retornan luego de recibir un corte de
pelo.
○ proximo_cliente → llamado por el peluquero para esperar que un cliente se siente en
su silla, y luego le corta el pelo.
○ corte_terminado → llamado por el peluquero para que el cliente deje la peluquería.
● Etapas de sincronización entre un cliente y el peluquero (rendezvous):
1. El peluquero tiene que esperar a que llegue un cliente, y este tiene que esperar que el
peluquero esté disponible.
2. El cliente necesita esperar que el peluquero termine de cortar el pelo para poder irse.
3. Antes de cerrar la puerta de salida, el peluquero necesita esperar hasta que el cliente
se haya ido.
25
● El tiempo de acceso al disco depende de:
A. Seek time para mover una cabeza al cilindro apropiado.
B. Rotational delay.
C. Transmission time (depende solo del número de bytes).
● A. y B. dependen del estado del disco (en qué cilindro, en qué sector está y hacia dónde
tengo que ir) → buscamos minimizar el tiempo de seek.
● Políticas de Scheduling de un disco:
○ Shortest-Seek-Time (SST).
○ SCAN, LOOK, o algoritmo del ascensor.
○ CSCAN o CLOOK
■ Se atienden pedidos en una sola dirección. Es fair y reduce la varianza del
tiempo de espera.
■ Este es el que nos interesa.
26
○ Pasaje de Mensajes Asincrónicos (PMA).
○ Pasaje de Mensajes Sincrónicos (PMS).
○ Llamado a Procedimientos Remotos (RPC).
○ Rendezvous.
Canal Mailbox
● En estos canales cualquier proceso puede enviar o recibir por alguno de los canales
declarados.
● Pueden haber varios emisores y varios receptores en el mismo canal.
Canal Link
● En estos canales solo puede haber un receptor y un emisor.
27
● Los monitores combinan Exclusión Mutua implícita y señalización explícita.
● Pasaje de Mensajes extiende semáforos con datos.
● RPC y Rendezvous combinan la interfaz procedural de monitores con PM implícito.
Filtros
● Proceso que recibe mensajes de uno o más canales de entrada y envía mensajes a uno o
más canales de salida.
● La salida de un filtro es función de su estado inicial y de los valores recibidos.
● Esta función del filtro puede especificarse por un predicado que relacione los valores de los
mensajes de salida con los de entrada.
28
● Para saber la cantidad de procesos de la red hacemos 𝑁 − 1 siendo N la cantidad de
números a ordenar.
● Para saber el ancho de la red hacemos 𝑙𝑜𝑔2(𝑁) siendo N la cantidad de números a ordenar.
● Puede programarse usando:
○ Static Naming:
■ Arreglo global de canales, y cada instancia de Merge recibe 2 elementos del
arreglo y envía otro.
○ Dynamic Naming:
■ Canales globales, parametrizar los procesos, y darle a cada proceso 3
canales al crearlo; todos los Merge son idénticos pero se necesita un
coordinador.
Clientes y Servidores
● Servidor:
○ Proceso que maneja pedidos de otros procesos clientes.
● Cliente:
○ Procesos que envían mensajes a un canal de requerimientos general, luego reciben
los resultados desde un canal de respuesta propio.
29
Comunicación para 1 operación
Continuidad Conversacional
● Un proceso cliente hace un requerimiento a un proceso servidor y una vez que el servidor lo
atiende el proceso cliente comienza a realizar varios requerimientos hasta que no le quedan
requerimientos para hacer, recién en este punto el servidor vuelve a quedar libre.
30
Solución Simétrica
● Es la solución más corta y sencilla de programar.
● Hay un canal entre cada par de procesos.
● Usa el mayor número de mensajes si es que no hay broadcast:
○ Sin broadcast son 𝑁 * (𝑁 − 1) mensajes siendo N la cantidad de procesos.
○ Con broadcast son N mensajes.
Solución Centralizada
● Se envían mensajes a un coordinador casi al mismo tiempo, solo el primer receive del
coordinador demora mucho.
● Usa un número lineal de mensajes.
○ 2 * (𝑁 − 1) mensajes.
Solución Anillo
● En esta solución todos los procesos son productores y consumidores. El último tiene que
esperar a que todos los demás (uno por vez) reciban un mensaje, hacer poco cómputo, y
enviar su resultado.
● Los mensajes circulan 2 veces completas por el anillo.
● Es una solución lineal y lenta.
● Usa un número lineal de mensajes.
○ (2 * 𝑁) − 1 mensajes.
31
CSP - Lenguaje para Pasaje de Mensajes Sincrónicos
● Canal:
○ Link directo entre dos procesos en lugar de mailbox global. Son halfduplex y
nominados.
● Las sentencias de Entrada (? o query) y Salida (! o shriek o bang) son el único medio por el
cual los procesos se comunican.
● Para que se produzca la comunicación, deben matchear, y luego se ejecutan
simultáneamente.
● Efecto: sentencia de asignación distribuida.
Comunicación guardada
● Las operaciones de comunicación (? y ! ) pueden ser guardadas, es decir hacer un AWAIT
hasta que una condición sea verdadera → El do e if de CSP usan los comandos guardados de
Dijkstra.
● Permite a los procesos comunicarse de forma no determinística y selectiva. En lugar de
bloquearse en una operación de entrada o salida, un proceso puede esperar a que se
cumplan ciertas condiciones o a que se reciban mensajes específicos.
● Brinda:
○ Flexibilidad en la comunicación.
○ Prevención de bloqueos.
○ Manejo eficiente de la concurrencia.
● Tienen la forma 𝐵; 𝐶 → 𝑆;
Ejecución
1. Primero, se evalúan las guardas:
a. Si todas las guardas fallan, el if termina sin efecto.
b. Si al menos una guarda tiene éxito, se elige una de ellas (no deterministicamente).
c. Si algunas guardas se bloquean, se espera hasta que alguna de ellas tenga éxito.
32
2. Segundo, luego de elegir una guarda exitosa, se ejecuta la sentencia de comunicación de la
guarda elegida.
3. Tercero, se ejecuta la sentencia Si.
● La ejecución del “do” es similar (se repite hasta que todas las guardas fallen).
33
Paradigmas de Interacción entre Procesos
● 3 esquemas básicos de interacción entre procesos:
○ productor/consumidor, cliente/servidor e interacción entre pares.
● Estos esquemas básicos se pueden combinar de muchas maneras, dando lugar a otros
paradigmas o modelos de interacción entre procesos.
Paradigma Master/Worker
● El concepto de bag of tasks usando variables compartidas supone que un conjunto de
workers comparten una “bolsa” con tareas independientes. Los workers sacan una tarea de la
bolsa, la ejecutan, y posiblemente crean nuevas tareas que ponen en la bolsa.
● Este paradigma es la implementación distribuida del modelo de bag of tasks que consiste en
un proceso controlador de datos y/o procesos y múltiples procesadores que acceden a él
para poder obtener datos y/o tareas para ejecutarlos en forma distribuida.
Paradigma Heartbeat
● Los procesos periódicamente deben intercambiar información y para hacerlo ejecutan dos
etapas; en la primera se expande enviando información (SEND a todos) y en la segunda se
contrae adquieren información (RECEIVE de todos).
● Su uso más importante es paralelizar soluciones iterativas.
Paradigma Pipeline
● Pipeline:
○ Arreglo lineal de procesos “filtro” que reciben datos de un puerto (canal) de entrada y
entregan resultados por un canal de salida.
● La información recorre una serie de procesos utilizando alguna forma de receive/send donde
la salida de un proceso es la entrada del siguiente.
● Esquemas posibles:
○ Esquema a lazo abierto:
■ W1 en el INPUT, Wn en el OUTPUT.
○ Esquema de pipeline circular:
■ Wn se conecta con el W1.
○ Esquema cerrado:
■ Un proceso coordinador maneja la realimentación entre Wn y W1.
Paradigma Probe/Echo
● Se basa en el envío de un mensaje (“probe”) de un nodo al sucesor, y la espera posterior del
mensaje de respuesta (“echo”).
● Los probes se envían en paralelo a todos los sucesores.
34
Paradigma Broadcast
● Permiten alcanzar una información global en una arquitectura distribuida. Sirven para la toma
de decisiones descentralizadas y para resolver problemas de sincronización distribuida.
● En este paradigma, un proceso envía un mensaje idéntico a todos los demás procesos en el
sistema.
● Broadcast no es atómico y los mensajes enviados por procesos A y B podrían ser recibidos
por otros en distinto orden.
RPC y Rendezvous
● Tanto RPC (Llamada a Procedimiento Remoto) como Rendezvous son mecanismos de
comunicación y sincronización entre procesos en sistemas distribuidos, especialmente
adecuados para aplicaciones cliente/servidor. Ambos combinan una interfaz similar a la de
los monitores, con operaciones exportadas invocables mediante llamadas externas (CALL),
con el uso de mensajes sincrónicos. Esto significa que el proceso que realiza la llamada se
bloquea hasta que la operación llamada se complete y se devuelvan los resultados.
○ El Pasaje de Mensajes se ajusta bien a problemas de filtros y pares que interactúan,
ya que se plantea la comunicación unidireccional.
○ RPC y Rendezvous se ajustan bien a problemas de cliente y servidor ya que usan
técnicas de comunicación y sincronización que suponen un canal bidireccional, lo
que es ideal para ese tipo de problemas.
35
Similitudes
● Interfaz similar a un monitor: Ambos mecanismos permiten definir módulos con operaciones
(o procedimientos) exportadas que pueden ser invocadas por procesos en otros módulos.
● Comunicación sincrónica: En ambos casos, la llamada a una operación es bloqueante. El
proceso llamador se suspende hasta que el proceso servidor complete la operación y
devuelva los resultados.
● Orientación a Cliente/Servidor: RPC y Rendezvous son especialmente útiles para
implementar interacciones cliente/servidor, donde un servidor ofrece servicios a múltiples
clientes.
Diferencias
● Manejo de la invocación: La principal diferencia radica en cómo se maneja la invocación de
una operación:
○ RPC: Se crea un nuevo proceso (o se utiliza uno de un pool preexistente) para
manejar cada llamada. El proceso servidor ejecuta el procedimiento correspondiente
a la operación, envía los resultados al llamador y finaliza.
○ Rendezvous: La Invocación se realiza mediante un "encuentro" (rendezvous) con un
proceso servidor ya existente. Este proceso utiliza una sentencia de entrada (in) para
esperar una invocación, procesarla y devolver los resultados. La atención de las
operaciones se realiza de forma secuencial, no concurrente.
● Sincronización:
○ RPC: El mecanismo en sí mismo sólo proporciona comunicación. La sincronización
entre los procesos dentro de un módulo debe programarse explícitamente utilizando
semáforos, monitores u otros mecanismos.
○ Rendezvous: Combina comunicación y sincronización. La sentencia de entrada (in)
del proceso servidor se encarga de la sincronización, bloqueando al servidor hasta
que llegue una invocación y al cliente hasta que se complete la operación.
36
● Es necesario proveer sincronización dentro de los módulos porque los procesos pueden
ejecutarse concurrentemente. Estos mecanismos de sincronización pueden usarse tanto
para el acceso a variables compartidas como para sincronizar interacciones entre los
procesos si fuera necesario.
Rendezvous
● Combina comunicación y sincronización.
● Como con RPC, un proceso cliente invoca una operación por medio de un call, pero esta
operación es servida por un proceso existente en lugar de por uno nuevo.
● Un proceso servidor usa una sentencia de entrada para esperar por un call y actuar.
● Las operaciones se atienden una por vez más que concurrentemente.
● A diferencia de RPC el servidor es un proceso activo.
Comunicación Guardada
● La sentencia "select" permite al servidor elegir entre diferentes alternativas de accept.
● Cada línea del select es una "alternativa" que puede incluir una cláusula "when" para
especificar una condición.
● Se puede usar "else", "delay" o "terminate" en las alternativas.
37
Thread
● Proceso “liviano” que tiene su propio contador de programa y su pila de ejecución, pero no
controla el “contexto pesado” (por ejemplo, las tablas de página).
38
Funciones
● int pthread_mutex_lock ( pthread_mutex_t *mutex);
○ Bloquear.
● int pthread_mutex_unlock (pthread_mutex_t *mutex);
○ Desbloquear.
● int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *lock_attr);
○ Se usa para inicializar un mutex.
○ Argumentos:
■ El primero es un puntero a una variable del tipo pthread_mutex_t que se va a
inicializar como un mutex.
■ El segundo es un puntero a una estructura de atributos del mutex. Se puede
usar para configurar el comportamiento del mutex (por ejemplo, si es
recursivo, el protocolo de bloqueo, etc.).
● Tipos de mutex:
○ Normal:
■ Un Mutex con el atributo Normal NO permite que un
thread que lo tiene bloqueado vuelva a hacer un lock
sobre él (deadlock).
○ Recursive:
■ Un Mutex con el atributo Normal SI permite que un
thread que lo tiene bloqueado vuelva a hacer un lock
sobre él (deadlock).
○ Error Check:
■ Trabaja como el normal, solo que en lugar de dejar
bloqueado al proceso, se informa error.
● Para evitar tiempos ociosos se puede utilizar la función pthread_mutex_trylock. Que retorna
el control informando si pudo hacer o no el lock.
○ Es no bloqueante:
■ Si un mutex está desbloqueado, lo bloquea e informa que se puedo realizar el
bloqueo; si un mutex está bloqueado, informa que no se puede hacer el
bloqueo y retorna el control.
Funciones
● int pthread_cond_wait ( pthread_cond_t *cond, pthread_mutex_t *mutex)
○ Se usa para que un hilo espere una condición mientras mantiene la sincronización
con un mutex. Se usa para evitar esperas activas y garantizar que un hilo solo
continúe su ejecución cuando una determinada condición sea señalada por otro hilo.
○ El hilo se duerme si la variable es falsa, continua si es verdadera.
39
● int pthread_cond_timedwait ( pthread_cond_t *cond, pthread_mutex_t *mutex const struct
timespec *abstime)
○ Se usa para que un hilo espere una condición durante un tiempo limitado mientras
mantiene la sincronización con un mutex. Si la condición no se cumple dentro del
tiempo especificado, la función termina con un error indicando que el tiempo expiró.
● int pthread_cond_signal (pthread_cond_t *cond)
○ Se usa para despertar un solo hilo que está esperando en una variable de condición.
● int pthread_cond_broadcast (pthread_cond_t *cond)
○ Se usa para despertar a todos los hilos que están esperando en una variable de
condición.
● int pthread_cond_init ( pthread_cond_t *cond, const pthread_condattr_t *attr)
○ Se usa para inicializar una variable de condición.
○ Argumentos:
■ El primero es un puntero a la variable de condición que se va a inicializar.
■ El segundo es un puntero a una estructura de atributos (pthread_condattr_t).
Permite establecer atributos específicos para la variable de condición, como
si se compartirá entre procesos o no.
● int pthread_cond_destroy (pthread_cond_t *cond)
○ Se usa para destruir una variable de condición previamente inicializada con
pthread_cond_init. Esta función libera los recursos asignados a la variable de
condición.
Attribute Object
● API Pthreads permite que se pueda cambiar los atributos por defecto de las entidades,
utilizando attributes objects.
● Es una estructura de datos que describe las propiedades de la entidad en cuestión (thread,
mutex, variable de condición).
● Una vez que estas propiedades están establecidas, el attribute object es pasado al método
que inicializa la entidad.
● Ventajas:
○ Mejora la modularidad.
○ Facilidad de modificación del código.
Semáforos
● Los threads se pueden sincronizar por semáforos (librería semaphore.h).
● Algunas Funciones:
○ sem_t semáforo
■ Se declaran globales a los threads.
○ sem_init (&semáforo, alcance, inicial)
■ En esta operación se inicializa el semáforo. Inicial es el valor con que se
inicializa el semáforo. Alcance indica si es compartido por los hilos de un
único proceso (0) o por los de todos los procesos ( ≠ 0).
○ sem_wait(&semáforo)
■ Equivale al P.
○ sem_post(&semáforo)
■ Equivale al V.
40
Monitores
● No se posee Monitores pero con la exclusión mutua y la sincronización por condición se
pueden simular.
○ El acceso exclusivo al monitor se simula usando una variable mutex la cual se
bloquea antes de la llamada al procedure y se desbloquea al terminar el mismo (una
variable mutex diferente para cada monitor).
○ Cada llamado de un proceso a un procedure de un monitor debe ser reemplazado por
el código de ese procedure.
Funciones
● MPI_init:
○ Inicializar entorno MPI.
● MPI_finalize:
○ Cerrar entorno MPI.
● MPI_common_size y MPI_common_rank:
○ Cantidad de procesos en el comunicador e identificador del proceso dentro del
comunicador.
41
● MPI_send y MPI_recv:
○ Ambos bloqueantes.
● MPI_Isend y MPI_Irecv:
○ No bloqueantes.
Comunicadores
● Un comunicador define el dominio de comunicación.
● Cada proceso puede pertenecer a muchos comunicadores.
● Existe un comunicador que incluye todos los procesos de la aplicación MPI_COMM_WORLD.
● Son variables del tipo MPI_Comm
○ Almacena información sobre qué procesos pertenecen a él.
● En cada operación de transferencia se debe indicar el comunicador sobre el que se va a
realizar.
42
○ Redes dinámicas: Están construidas usando switches y enlaces de comunicación.
Normalmente para máquinas de memoria compartida.
43
SIMD - Single Instruction Multiple Data
● Tiene múltiples flujos de datos pero sólo un flujo de instrucción.
● En particular, cada procesador ejecuta exactamente la misma secuencia de instrucciones, y
lo hacen en un lockstep.
○ Esto hace a las máquinas SIMD especialmente adecuadas para ejecutar algoritmos
paralelos de datos.
● Logra un paralelismo a nivel de datos, o sea ejecuta la misma instrucción en todos los
procesadores.
Descomposición de Datos
● Determinar una división de los datos y luego asociar el cómputo:
44
○ Esto da un número de tareas, donde cada uno comprende algunos datos y un
conjunto de operaciones sobre ellos. Una operación puede requerir datos de varias
tareas, y esto llevará a la comunicación.
○ Son posibles distintas particiones, basadas en diferentes estructuras de datos.
Descomposición Funcional
● Primero descompone el cómputo en tareas disjuntas y luego trata los datos.
○ La descomposición funcional tiene un rol importante como técnica de estructuración
del programa, para reducir la complejidad del diseño general.
Aglomeración
● El algoritmo resultante de las etapas anteriores es abstracto en el sentido de que no es
especializado para ejecución eficiente en una máquina particular.
● Esta etapa revisa las decisiones tomadas con la visión de obtener un algoritmo que ejecute
en forma eficiente en una clase de máquina real.
● En particular, se considera si es útil combinar o aglomerar las tareas para obtener otras de
mayor tamaño. También se define si vale la pena replicar datos y/o computación.
45
■ Poner tareas que se comunican con frecuencia en iguales procesadores para
incrementar la localidad.
● El problema es NP-completo:
○ No existe un algoritmo de tiempo polinomial tratable computacionalmente para
evaluar tradeoffs entre estrategias en el caso general. Existen heurísticas para clases
de problema.
● Normalmente tendremos más tareas que procesadores físicos.
● Los algoritmos paralelos (o el scheduler de ejecución) deben proveer un mecanismo de
“mapping” entre tareas y procesadores físicos.
● Nuestro lenguaje de especificación de algoritmos paralelos debe poder indicar claramente las
tareas que pueden ejecutarse concurrentemente y su precedencia/prioridad para el caso que
no haya suficientes procesadores para atenderlas.
● La dependencia de tareas condicionarán el balance de carga entre procesadores.
● La interacción entre tareas debe tender a minimizar la comunicación de datos entre
procesadores físicos.
Métrica de Speedup
● 𝑆 = 𝑇𝑠 / 𝑇𝑝
○ S es el cociente entre el tiempo de ejecución secuencial del algoritmo secuencial
conocido más rápido (Ts) y el tiempo de ejecución paralelo del algoritmo elegido
(Tp).
○ El rango de valores de S va desde 0 a p, siendo p el número de procesadores.
○ Mide cuánto más rápido es el algoritmo paralelo con respecto al algoritmo
secuencial, es decir, cuánto se gana por usar más procesadores.
Métrica de Eficiencia
● 𝐸 = 𝑆/𝑃
○ Cociente entre speedup y número de procesadores.
○ El valor está entre 0 y 1, dependiendo de la efectividad en el uso de los procesadores.
Cuando es 1 corresponde al speedup perfecto.
○ Mide la fracción de tiempo en que los procesadores son útiles para el cómputo, es
decir cuánto estoy usando de los recursos disponibles.
Programa Paralelizado
● En cualquier programa paralelizado existen dos tipos de código; el código paralelizado y el
código secuencial.
46
● Existen ciertas secciones de código que ya sea por dependencias, por acceso a recursos
únicos o por requerimientos del problema no pueden ser paralelizadas. Estas secciones
conforman el código secuencial, que debe ser ejecutado por un solo elemento del
procesador.
● Entonces, es lógico afirmar que la mejora del speedup de un programa dependerá del
tiempo en el que se ejecuta el código secuencial, el tiempo en el que se ejecuta el código
paralelizable y el número de operaciones ejecutadas de forma paralela.
Ley de Amdahl
● Enuncia que para cualquier tipo de problema existe un máximo speedup alcanzable que no
depende de la cantidad de procesadores que se utilicen para resolverlo. Esto es así porque
llega un momento en que no existe manera de aumentar el paralelismo de un programa.
47