Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Cecilia Hernndez
Motivacin
Hebras realizan trabajo en conjunto en una aplicacin multihebra Uno espera resultados determinsticos (ante una misma entrada obtener misma salida) Si no hay comparticin de datos entre hebras
Coordinan su ejecucin
Ejemplo, productores que generan informacin que pasan a consumidores que consumen informacin
Motivacin
Por qu se comparte?
Costo
Una impresora con muchos archivos, una carretera con muchos autos, un multicore con muchos procesos
Informacin
Una hebra puede necesitar los datos generados por otra Mejora tiempo de ejecucin Proporciona modularidad, tareas separadas por actividades las que se comunican slo cuando es necesario
Motivacin
Posibles inconsistencias
R1 = X R1 = R1 + 1 X = R1
Posibles inconsistencias
H1 X=6 R1 = X R1 = R1 + 1 Cambio contexto R2 = X R2 = R2 - 1 Cambio contexto X = R1 Cambio contexto X = R2 X=7 X=5 H2 X=6
Sincronizacin
El nico supuesto vlido es que hebras ejecutan sus instrucciones en forma entrelazada
SOs modernos son apropiativos Mquinas actuales son multicore No se pueden asumir tiempos de ejecucin (nunca usar sleep(n) para demorar la ejecucin entre hebras)
Algunas aplicaciones requieren patrones de ejecucin con concurrencia y dependencia de orden de ejecucin Control de cooperacin se realiza mediante mecanismos de sincronizacin Sincronizacin tambin se aplica a procesos (no slo hebras) y a procesos en un sistema distribuido
Comparticin de recursos
Problema bsico
Cules son en hebras?, en procesos? Si variables se leen, modifican, escriben concurrentemente entonces su acceso debe realizarse en forma controlada
Veremos
Locks, mutexes, variables de condicin, semforos y monitores Productores/consumidores, lectores/escritores, filsofos comensales
Ejemplo clsico
Ejemplo clsico
Qu pasa si tiene cuenta compartida con su mam (con saldo $1000) y ambos van a 2 cajeros a Girar(100) concurrentemente
int Girar(Cuenta c, int cantidad) { int balance = get_balance(c); balance -= cantidad; set_balance(c, balance); return balance; }
int Girar(Cuenta c, int cantidad) { int balance = get_balance(c); balance -= cantidad; set_balance(c, balance); return balance; }
Ejemplo clsico
balance = get_balance(c, cantidad); balance -= cantidad; Cambio contexto balance = get_balance(c, cantidad); balance -= cantidad; set_balance(c, balance); Cambio contexto set_balance(c, balance);
Quin gana, su cuenta o el banco? Identifique que entrelado proporcionara resultados correctos y cules no.
Cul es el problema?
Detectar estos problemas es muy difcil porque no se reproducen fcilmente Estos problemas se llaman condiciones de carrera Variables globales y memoria dinmica Archivos, puertos de conexin
Usando mecanismos de sincronizacin Idea es controlar acceso a recursos compartidos haciendo que slo una hebra a la vez pueda accesar recurso compartido
Se llama exclusin mutua Segmento de cdigo que accesa a recurso compartido se llama seccin crtica Idea es que slo se proteja seccin crtica y no otro cdigo
Definiciones
Condicin de carrera
Salida de programa concurrente depende del orden en que se ejecutan las instrucciones produciendo inconsistencias Slo una hebra a la vez puede accesar recurso compartido Segmento de cdigo que slo una hebra a la vez puede ejecutar Primitiva bsica para asegurar exclusin mutua, asegurando que slo una hebra a la vez pueda accesar a seccin crtica
Exclusin mutua
Seccin crtica
Lock
Si una hebra no est en seccin crtica no debe impedir que otra que quiera entrar entre Si una hebra est esperando entrar a seccin crtica eventualmente debe tener xito La sobrecarga de uso de sincronizacin debe ser mucho menor que el tiempo de ejecucin de seccin crtica
Espera finita
Eficiencia
Mecanismos de sincronizacin
Locks
Semntica mnima, sirven para construir otros mecanismos mas complejos Idea basada en la idea que hebra debe esperar (wait) por la ocurrencia de un evento antes de seguir, para ello otra hebra le avisar cuando eso ocurra (signal) Bsicos, accesibles en SOs (llamado a sistema semget() en linux) Fcil de cometer errores Alto nivel, requiere soporte del lenguaje de programacin Ms modular que semforos, en java se usa synchronized como base para construirlos Modelo simple de comunicacin y sincronizacin basado en transferencia de datos atmica a travs de un canal Aplicacin directa a sistemas distribuidos (RPC, Java RMI)
Variables de condicin
Semforos
Monitores
Mensajes
Locks
release()/unlock(): Hebra la llama despus de salir de S.C. Entre que se llama acquire y release hebra mantiene el lock Qu pasa si acquire()/release() no se usan en pares? Spinlocks (no bloqueante, espera ocupada (busy-waiting)) Mutex (bloqueante)
2 tipos de locks
Using locks
H1 X++; H1 acquire(lock) R1 = X R1 = R1 + 1 X = R1 realease(lock) acquire(lock) R1 = X R1 = R1 + 1 acquire(lock) X = R1 release(lock) R2 = X R2 = R2 1 X = R2 release(lock) H2 X--; H2 acquire(lock) R2 = X R2 = R2 1 X = R2 realease(lock)
Using locks
int Girar(Cuenta c, int cantidad) { int balance = get_balance(c); balance -= cantidad; set_balance(c, balance); return balance; }
int Girar(Cuenta c, int cantidad) { int balance = get_balance(c); balance -= cantidad; set_balance(c, balance); return balance; }
Use locks para evitar condicin de carrera Cules son las secciones crticas? Secuencia de operaciones y estados
Lock: acquire/release
acquire(lock)
Seccin crtica
release(lock)
Spinlocks
Implementacin de locks
Deshabilitar/habilitar interrupciones
Instrucciones atmicas (test and set, cmp and swap) Qu pasa en multiprocesadores?
Idea is desabilitar las interrupciones en acquire() y habiliarlas en release() Quin podra hacer esto? Es esto suficiente en un sistema con mltiples procesadores?
target = 0
target = 1
Si hebra est en loop esperando por adquirir lock, la hebra que tiene lock no puede progresar
hebras que estn esperando en spinlock, incluso hebra que tiene lock
Por qu? Contencin en protocolo de coherencia de memoria Cuando hebra tiene xito invalidacin de caches locales
Cuando tiempo de espera para conseguir lock es corto se pueden usar spinlocks (eficientes) y no hay demasiadas hebras esperando por lock
Desempeo
Si hebra obtiene lock despus de M ciclos de espera ocupada (spinning) (M <= N) entonces M es el costo ptimo
Alternativa de bloqueo inmediato habra sido el costo N, con spinning conseguimos M Si hebra espera por N ciclos spinning y luego se bloquea y resume porque lock fue liberado Costo bloqueo en 2N ( N para spinning y N para bloqueo y resumen de hebra) Desempeo siempre un factor de de 2 del ptimo
Peor caso
Escriba un programa multihebra que cree 2000 hebras, 1000 incrementan una variable global y 1000 que la decrementan e imprima valor final
Entregar valor inicial de la variable en argumento Leer el valor final desde la hebra principal (la que crea las hebras sumadoras y las restadoras) Compile (acurdese de -pthread en lnea de compilacin) y ejecute. Observe si ve diferencia en el valor de retorno del valor final en la variable global Agregue mutexes para solucionar sus problemas Mida tiempos de ejecucin con y sin sincronizacin
Semforos
Primitiva de sincronizacin ms elaborada que mutex (locks) Inventados por Dijkstra (en SO THE implementado por niveles) Objeto atmico con valor y cola de espera Operaciones P(sem) y V(sem)
P(sem)/Wait(sem)/Down(sem):
Sem.valor-If (sem.valor < 0) bloquea hebra (agrega a cola de espera) Else hebra puede entrar a Seccin crtica Sem.valor++; If (Existe hebra en cola de espera) despierta a una
V(sem)/Signal(sem)/Up(sem)
(= 1 es como lock)
Implementacin de semforos
typedef struct { int valor; struct hebra *L; } semaforo; void wait(semaforo S) { S.valor--; if (S.valor < 0){ agregar hebra a S.L; block(); } } void signal(semaforo S){ S.valor++; if (S.valor <= 0){ remover hebra T de S.L; wakeup(T); } }
Tipos de semforos
Binarios (mutex)
Garantizan exclusin mutua Contador (valor) de semforo inicializado en 1 Representan recursos con mas de una unidad disponible Contador inicializado en N
Contadores
Productor/consumidor
X hebras productoras generan informacin que agregan a cola Y hebras consumidoras extraen informacin de cola
Algoritmo Productor/Consumidor
int contador = 0; //indica nmero de items en buffer Tipo buffer[N]; int in = 0; int out = 0;
Productor while (true) { /* produce un item en proxProd */ while (contador == N); //espera buffer[in] = proxProd; in = (in + 1) % N; contador++; }
Consumidor while (true) { while (contador == 0); //espera proxCons = buffer[out]; out = (out + 1) % N; contador--; /* consume prodCons */ }
Condiciones de carrera?
Cmo ?
Mutex? Contadores?
Proporcionar algoritmos