capitulo 2(cont) · operating system concepts – 9th edition 4.9 silberschatz, galvin and gagne...
TRANSCRIPT
Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Capitulo 2(cont): Comunicación y sincronización entre
procesos
4.2 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Programación Multicore Modelos de subprocesos múltiples Bibliotecas Thread Threading implicito Problemas de threads Ejemplos de sistemas operativos
4.3 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Motivación
Las aplicaciones más modernas son multihilo Hilos ejecutar dentro de la aplicación Varias tareas con la aplicación se puede implementar por hilos
separados Actualización de la pantalla Recoger datos Corrección ortográfica Responder a una solicitud de red
La creación de procesos es de gran peso, mientras que la creación del hilo es de peso ligero
Se puede simplificar el código, aumentar la eficiencia Los nucleos son generalmente multihilo
4.4 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Arquitectura de servidor multiproceso
4.5 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Beneficios
Capacidad de respuesta – podría permitir que la ejecución continue, si parte del proceso se bloquea, especialmente importante para las interfaces de usuarios
Intercambio de recursos – los hilos comparten recursos de procesos, más fácil que la memoria compartida o paso de mensajes
Economía– más barato que la creación de procesos, hilos de conmutación producen menor sobrecarga que el cambio de contexto
Escalabilidad – proceso puede tomar ventaja de las arquitecturas multiprocesador
4.6 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Programación multicore Multicore o sistemas multiprocesador poniendo presión sobre los programadores, los desafíos
incluyen: La división de las actividades Balance División de datos Dependencia de datos Probar y depurar
Paralelismo implica un sistema que puede realizar más de una tarea al mismo tiempo Concurrencia admite más de una tarea haciendo progresos
Solo procesador / núcleo, proporcionando planificador de concurrencia Tipos de paralelismo
Paralelismo de datos - distribuye los subconjuntos de los mismos datos en múltiples núcleos, la misma operación en cada uno
Paralelismo de tareas - la distribución de hilos a través de los núcleos, cada subproceso realiza una operación única
Como N º de hilos crece, también crece el apoyo estructural para threading CPUs tienen núcleos, así como hilos de hardware Oracle T4 con 8 núcleos de SPARC, y 8 subprocesos de hardware por núcleo
4.7 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Procesos simples and Multihilo
4.8 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Concurrencia vs. Paralelismo
Concurrent execution on single-core system:
Parallelism on a multi-core system:
4.9 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Ley de Amdahl Identifica ganancias en rendimiento al añadir núcleos adicionales en una aplicación que tiene
componentes seriales y paralelos S es la fracción serial N núcleos de procesamiento
Es decir si la aplicación es 75% paralela / serial 25%, aumentando de 1 a 2 núcleos resulta en un aumento de velocidad (speed up) de 1,6 veces
Como N tiende a infinito, aumento de velocidad se aproxima a 1 / S
La fracción serial es una aplicación sobre el efecto desproporcionado ocasionado en el rendimiento obtenido mediante la adición de núcleos adicionales
Pero, ¿la ley toma en cuenta los actuales sistemas multi-núcleo?
4.10 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Hilos de usuario e hilos de kernel
Hilos de usuarios – manejo hecho por la librería de hilos de nivel de usuario Three primary thread libraries:
POSIX Pthreads Win32 threads Java threads
Hilos de Kernel – Soportados por el Kernel Ejemplos – prácticamente todos los sistemas operativos de propósito general,
incluyendo: Windows Solaris Linux Tru64 UNIX Mac OS X
4.11 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Multithreading Models
Muchos a uno
Uno a uno
Muchos a muchos
4.12 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Muchos a uno
Muchos hilos a nivel de usuario asignado a un solo hilo del kernel
Un hilo de bloqueo provoca que todos los hilos bloqueen
Varios hilos no pueden ejecutarse en paralelo en el sistema multicore porque sólo uno puede estar en el kernel a la vez
Pocos sistemas actualmente utilizan este modelo
Ejemplos: Solaris Green Threads GNU Portable Threads
4.13 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Uno a uno
Cada hilo de nivel de usuario se asigna a un hilo de kernel Creando un hilo de nivel de usuario se crea un hilo de kernel Mayor concurrencia que en el modelo anterior El número de hilos por proceso esta restringido por la sobrecarga
Ejemplos Windows NT/XP/2000 Linux Solaris 9 y posteriores
4.14 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Modelo muchos a muchos
Permite que muchos hilos de nivel usuario sean asignados a muchos hilos de kernel
Permite al S.O crear un número suficiente de hilos de kernel
Solaris posterior a version 9
Windows NT/2000 con el paquete ThreadFiber
4.15 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Modelo dos niveles
Similar a muchos a muchos , excepto porque permite al hilo de usuario ser limitado por el hilo de kernel
Ejemplo IRIX HP-UX Tru64 UNIX Solaris 8 y anteriores
4.16 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Bibliotecas Thread
Thread library provee al programador una API para crear y gestionar hilos
Existen 2 formas de implementarlos Librería completa en espacio de usuario Librería de nivel kernel soportada por el S.O
4.17 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Pthreads
Puede ser suministrada bien como a nivel de usuario o kernel-nivel
Un estándar POSIX (IEEE 1003.1c) API para la creación de subprocesos y la sincronización
Especificación, no implementación
API especifica el comportamiento de la biblioteca de hilos, la implementación depende el desarrollo de la biblioteca
Común en los sistemas operativos UNIX (Solaris, Linux, Mac OS X)
4.18 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Pthreads Ejemplo
4.19 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Pthreads Ejemplo (Cont.)
4.20 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Pthreads Código para juntar 10 hilos
4.21 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Java Threads
Típicamente implementada cuando el modelo de hilos que provee el S.O
Los hilos de Java pueden ser creados: Extendiendo la clase Thread Implementando la interfaz Runnable
4.22 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Programa de Java multihilo
4.23 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Programa de Java multihilo (Cont.)
4.24 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Threading implicito
Creciendo en popularidad a medida que el número de hilos aumenta, la correctes(z?) del programa es más difícil con hilos explícitos
Creación y gestión de hilos hechos por los compiladores y bibliotecas en tiempo de ejecución en lugar de ser hecha por programadores
Tres métodos explorados Thread Pools OpenMP Grand Central Dispatch
Otros métodos incluidos en Microsoft Threading Building Blocks (TBB), paquete java.util.concurrent
4.25 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Thread Pools
Crear un número de hilos en un “pool” donde esperan trabajo
Ventajas: Por lo general, es un poco más rápido atender una solicitud de un
hilo existente que crear un nuevo hilo Permite que el número de hilos en la aplicación esten sujetos al
tamaño de, “pool” La separación de tareas para llevar a cabo la creación de tareas
permite diferentes estrategias para la ejecución de la tarea es decir, las tareas se pueden programar para que se ejecute
periódicamente
API de Windows admite “pool” de hilos:
4.26 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
OpenMP
Conjunto de directivas de compiladores y una API para C, C++, FORTRAN
Proveer soporte para programación paralela en ambientes de memoria compartida
Identifica regiones paralelas – bloques de código que pueden ejecutarse en paralelo
#pragma omp parallel
Crea tantos hilos como cores existan
#pragma omp parallel for for(i=0;i<N;i++) {
c[i] = a[i] + b[i];
}
4.27 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Grand Central Dispatch
La tecnología de Apple para Mac OS X y sistemas operativos iOS Las extensiones a C, C + +, API y biblioteca en tiempo de ejecución Permite la identificación de las secciones paralelas Gestiona la mayor parte de los detalles de threading Bloques colocados en la cola de despacho
Asignado al hilo disponible en "pool" de hilo cuando se remueve de la cola Hay dos tipos de colas de despacho:
serial - Bloques retirados en orden FIFO, la cola es por proceso, llamado cola principal
Los programadores pueden crear colas adicionales seriales dentro del programa
concurrente - eliminado en orden FIFO pero se pueden extraer varios a la vez Tres colas en todo el sistema con prioridades bajas, por defecto, de alta
prioridad
4.28 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Ejemplos de S.O
Windows XP Threads
Linux Thread
4.29 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Windows Threads Windows implementA LA Windows API – API primaria para Win 98, Win NT, Win 2000,
Win XP, y Win 7
Implementa la asignación uno a uno en el nivel de kernel Cada hilo contiene
Un identificador de hilo (ID) Un conjunto de registros representando el estado del procesador Pilas separadas de usuario y kernel, para cuando el hilo se ejecuta en modo usuario o
modo kernel Área privada de almacenamiento usada por bibliotecas en tiempo de ejecución y por
bibliotecas de enlaces dinámicos (DLLs)
El conjunto de reistros, pilas y almacenamiento privado es conocido como el contexto del hilo
Las estructuras de datos primarias de un hilo incluyen: ETHREAD (executive thread block) – incluye apuntadores al proceso al cual el hilo
pertenece y a KTHREAD, en el espacio de kernel KTHREAD (kernel thread block) – información de planificación sincronización, pila de
mode kernel, puntero a TEB, en espacio de kernel TEB (thread environment block) – id del hilo, pila de modo usuario, almacenamiento
local de hilos en espacio de usuario
4.30 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Estructuras de datos de Windows XP Threads
4.31 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Linux Threads
Linux se refiere a ellos como tasks en lugar de threads
La creación de hilos se realiza a través de la llamada al sistema clone()
clone() permite que una tarea hijo comparta el espacio de direcciones de la tarea padre (proceso)
Banderas de control de comportamiento
struct task_struct puntos para procesar estructuras de datos (compartido o exclusivo))
4.32 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Sincronización de procesos
El problema de la sección crítica Solución de Peterson sincronización de Hardware Mutex Locks Semáforos Problemas clásicos de sincronización Monitores Ejemplos de sincronización Enfoques Alternativos
4.33 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Antecedentes Los procesos se pueden ejecutar concurrentemente
Puede ser interrumpido en cualquier momento, completando parcialmente ejecución
Acceso concurrente a datos compartidos puede dar lugar a incoherencias en los datos
Mantener la consistencia de datos requiere mecanismos para asegurar la ejecución ordenada de procesos cooperativos
Ilustración del problema:Supongamos que se quiere proporcionar una solución al problema del consumidor-productor que llena todos los búferes. Podemos hacerlo teniendo un contador de números enteros que realiza un seguimiento del número de buffers completos. Inicialmente, el contador se pone a 0. Se incrementa por el productor después de que se produce un nuevo buffer y se decrementa por el consumidor después de que se consume un búfer.
4.34 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Productor
while (true) {/* produce an item in next produced */
while (counter == BUFFER SIZE) ;
/* do nothing */
buffer[in] = next produced;
in = (in + 1) % BUFFER SIZE;
counter++;
}
4.35 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Consumidor
while (true) {
while (counter == 0)
; /* do nothing */
next consumed = buffer[out];
out = (out + 1) % BUFFER SIZE; counter--;
/* consume the item in next consumed */
}
4.36 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Condición de competencia
counter++ puede ser implementado como
register1 = counter register1 = register1 + 1 counter = register1
counter-- puede ser implementado como
register2 = counter register2 = register2 - 1 counter = register2
Considere esta ejecución traslapada con “count = 5” inicialmente:S0: productor ejecuta register1 = counter {register1 = 5}S1: productor ejecuta register1 = register1 + 1 {register1 = 6} S2: consumidor ejecuta register2 = counter {register2 = 5} S3: consumidor ejecuta register2 = register2 – 1 {register2 = 4} S4: productor ejecuta counter = register1 {counter = 6 } S5: consumidor ejecuta counter = register2 {counter = 4}
4.37 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Problema de la seccion crítica
Considera un sistema de n procesos {p0, p1, … pn-1}
Cada proceso tiene una sección crítica de segmento de código El proceso puede estar cambiando las variables comunes, actualizar
la tabla, escritura de archivos, etc Cuando un proceso en el la sección crítica, ningún otro puede estar
en su sección crítica
Problema de sección crítica es diseñar protocolo para resolver este
Cada proceso tiene que pedir permiso para entrar en su sección crítica en la sección de entrada, puede seguir con la sección crítica, sección de salida, entonces la sección restante
4.38 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Sección Critica
La estructura general del proceso pi es
4.39 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Solución al problema de la sección crítica1. Exclusión mutua – Si el proceso Pi está ejecutando su sección crítica, ningún
otro proceso puede estar ejecutando su sección crítica
2. Progreso - Si ningún proceso está ejecutando en su sección crítica y existen algunos procesos que desean entrar en su sección crítica, entonces la selección de los procesos que van a entrar en la sección crítica que viene no se puede posponer indefinidamente
3. Espera limitada - Un límite debe existir en el número de veces que otros procesos están autorizados a entrar en sus secciones críticas después de un proceso haya hecho una solicitud para entrar en su sección crítica y antes de que la solicitud se concede
Suponga que cada proceso se ejecuta a una velocidad distinta de cero No hay supuestos concernientes a la velocidad relativa de los n procesos
4.40 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Dos enfoques dependiendo de si el núcleo es apropiativo o no apropiativo- Apropiativo – permite la preferencia de un proceso cuando se ejecuta en modo
kernel Non-apropiativo – se ejecuta hasta que se sale del modo kernel, bloquea o
voluntariamente cede el CPU Esencialmente libera de las condiciones de competencia en modo kernel
4.41 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Solución de Peterson
Buena descripción algorítmica de solución el problema
Solución de 2 procesos
Suponga que las instrucciones load y store son atómicas, es decir, no pueden interrumpirse
Los dos procesos comparten dos variables: int turn; Boolean flag[2]
La variable turn indica de quién es el turno para entrar en la sección crítica
El arreglo flag se utiliza para indicar si un proceso está listo para entrar en la sección crítica. flag[i] = true mplica que el proceso Pi está listo!
4.42 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
do {
flag[i] = true;
turn = j;
while (flag[j] && turn == j);
critical section
flag[i] = false;
remainder section
} while (true);
Puede notarse que: 1. La exclusión mutua se conserva2. Se satisface el requisito de progreso3. El requisito de espera limitada se cumple
Algoritmo para el proceso Pi
4.43 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Hardware de sincronización Muchos sistemas proporcionan soporte de hardware para el código de la
sección crítica
Todas las soluciones basadas en la idea de bloquear La protección de las regiones críticas a través de candados
Uniprocesadores - podría deshabilitar las interrupciones Actualmente, ejecutar código podría ejecutarse sin apropiación En general muy ineficiente en sistemas multiprocesador
Los sistemas operativos que utilizan esto no son ampliamente escalables
Las máquinas modernas proveen instrucciones atómicas especiales de HW Atómica = no divisible
Ambas prueban (test) palabra de memoria y establecen (set) el valor O contenidos de swap de dos palabras de memoria
4.44 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
do {
acquire lock
critical section
release lock
remainder section
} while (TRUE);
Solución al problema de sección crítica usando Locks
4.45 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Instrucción test_and_set
Definición:
boolean test_and_set (boolean *target)
{
boolean rv = *target;
*target = TRUE;
return rv:
}
4.46 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Solución usando test_and_set()
La variable compartida lock es inicializada a FALSE Solución:
do { while (test_and_set(&lock))
; /* do nothing */
/* critical section */
lock = false;
/* remainder section */
} while (true);
4.47 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Instrucción compare_and_swap Instruction
Definición:
int compare and swap(int *value, int expected, int new value) {
int temp = *value;
if (*value == expected)
*value = new value;
return temp; ition
}
4.48 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Solución usando compare_and_swap
La variable compartida lock es inicializada a FALSE; Cada proceso tiene una variable local clave
Solución:
do { while (compare and swap(&lock, 0, 1) != 0)
; /* do nothing */
/* critical section */
lock = 0;
/* remainder section */
} while (true);
4.49 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Bounded-waiting Mutual Exclusion con test_and_set
do { waiting[i] = true; key = true; while (waiting[i] && key)
key = test_and_set(&lock);
waiting[i] = false;
/* critical section */
j = (i + 1) % n;
while ((j != i) && !waiting[j])
j = (j + 1) % n;
if (j == i)
lock = false;
else
waiting[j] = false;
/* remainder section */
} while (true);
4.50 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
Mutex Locks Las soluciones anteriores son complicadas y generalmente
inaccesibles a los programadores de aplicaciones Diseñadores OS construyen herramientas de software para resolver el
problema de la sección crítica La más simple es mutex lock Producto de regiones críticas primero se solicita un bloqueo con la
instrucción acquire() y luego se libera con la instrucción release()
Una variable booleana indica si el bloqueo esta disponible o no
Las llamadas a acquire() y release() deben ser atómicas Usualmente implementadas via instrucciones atómicas de HW
Pero esta solución requiere busy waiting ( ciclo de consulta constante del dispositivo, leyendo la puerta de control del dispositivo que le informa si tal evento ocurrió o no. En esta estrategia, este ciclo de consulta ocupa el 100% de tiempo de CPU y de ahí el nombre de busy-waiting.)
Este candado (o bloqueo) es llamado un spinlock
4.51 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition
acquire() y release()
acquire() { while (!available)
; /* busy wait */
available = false;;
}
release() {
available = true;
}
do {
acquire lock
critical section
release lock
remainder section
} while (true);