Descargar

Gestión de procesos. Sistemas operativos (página 2)

Enviado por Pablo Turmero


Partes: 1, 2
edu.red

13 Esbozo de implementación ( ¿Procesos bloqueados? ) espLapso => Muy parecido a preparados, sólo que es necesario indicar cuándo despertarles o cuánto falta para despertarles, … (Gp:) 1 (Gp:) 2 (Gp:) 3 (Gp:) 4 (Gp:) 97 (Gp:) 98 (Gp:) 99 (Gp:) 100 (Gp:) 50 (Gp:) type descriptorProceso is record pid: NATURAL; estado: unEstado; sig: idProceso; lapso: NATURAL; end record; espLapso : unaCola;

(Gp:) 10 (Gp:) 5 (Gp:) 25

El campo sig me sigue sirviendo para encadenar Otras formas de implementarlo: (Gp:) 5 (Gp:) 5 (Gp:) 15 (Gp:) 4 (Gp:) 50 (Gp:) 97

edu.red

14 Esbozo de implementación ( ¿Procesos bloqueados? ) espFinHijo => El fin de un hijo sólo puede estar esperándolo su Padre. Puede no ser necesaria una cola. type descriptorProceso is record pid: NATURAL; padre: idProceso; estado: unEstado; sig: idProceso; lapso: NATURAL; end record; El Padre (P) hace wait (H): — Localizar H en procesos => h if h.estado = zombie then Liberar recursos del Hijo y continuar al Padre else — hijo vivo p.estado:=espFinHijo; p.sig:=h; liberar CPU; Un Hijo(H) termina exit: If (p.estado = espFinHijo) & (p.sig = h) then liberar recursos Hijo y continuar Padre else h.estado := zombie y liberar CPU

edu.red

15 Esbozo de implementación ( Concluyendo ) maxProcesos : constant := 100; type idProceso is NATURAL range 0..maxProcesos; type unEstado is (ejecutandose, preparado, espLapso, espFinHijo, zombie); type descriptorProceso is record pid: NATURAL; padre: idProceso; estado: unEstado; sig: idProceso; lapso: NATURAL; SP: address; memoria: ———-; ficheros: ———-; tiempos: ———-; end record; type unaCola is record primero: idProceso := 0; ultimo: idProceso := 0; end record; procesos : array [1..maxProcesos] of descriptorProceso; ejecutandose: idProceso; preparados, espLapso: unaCola; ¿ fork y exec ?

edu.red

16 Campos en una entrada a la tabla de procesos Esbozo de implementación ( Otro ejemplo )

edu.red

17 Esbozo de implementación ( El Cambio de Contexto ) Causas? (Gp:) Llamada al Sistema Fin de Proceso Bien/Mal Interrupción

(Gp:) Trap (Gp:) (E/S, F.R.)

(Gp:) Mecanismo similar

Supongamos como causa "Fin de Rodaja" (Gp:) ejecu- tándose (Gp:) Pi

(Gp:) Hw (Gp:) (1)

(1) Reconocimiento de la interrupción (Gp:) S.O.

(Gp:) Pj

(Gp:) Ens. (Gp:) (2)

(2) Salvar reg (Pi) y conmutar de pila (Gp:) C/Modula/Ada (Gp:) (3)

(3) 1 Recorrer dormitorio 2 Elegir siguiente proceso (Gp:) Ens. (Gp:) (4)

(4) Recuperar reg (Pj) y cederle control (Gp:) Planificador

(Gp:) Dispatcher

¿No hay procesos preparados?

edu.red

18 (Gp:) Vector de Interrupciones (Gp:) S.O.

Esbozo de implementación ( El Cambio de Contexto ) ———- ———- sleep(10) ———- ———- exit(0) ——- ——- ——- ——- ——- ——- ——- ——- ——- ——- ——- ——- (Gp:) TRAP #0

——- ——- ——- ——- ——- (Gp:) INT 3

———- divu d5,d0 ———- ——- ——- ——- ——- ——- (Gp:) DIV 0

(Gp:) Se salva el SR y PC

(Gp:) ——- ——- ——- ——- ——- ——- ——- ——- (Gp:) Cambio de contexto

edu.red

19 Threads ( Visión abstracta ) Modelo de procesos más común ? Espacios de direcciones disjuntos (Gp:) Registros Código Datos, Pila Ficheros (Gp:) Pi

(Gp:) Registros Código Datos, Pila Ficheros (Gp:) Pj (Gp:) fork (Gp:) exec (Gp:) ls.exe

Facilita protección Pi?Pj, pero: Creación laboriosa Cambio de contexto pesado (procesador + entorno) TLB's, cachés, … Comunicación vía mensajes más seguro pero más lento ¿Y si los procesos son cooperantes? Objetivo común Colaboración vs agresión Protección más laxa Pueden desear mantener datos comunes con los menores costes de tiempo

edu.red

20 (Gp:) BD utilidades

Threads ( Visión abstracta ) Procesos Ligeros ? Espacios de direcciones no disjuntos (Gp:) Registros Pila (Gp:) Registros Pila (Gp:) Código, Datos Ficheros (Gp:) Ti (Gp:) Tj

Servidor de localización de utilidades (Gp:) C1 (Gp:) C2 (Gp:) Cn (Gp:) S

(Gp:) consulta

(Gp:) alta

(Gp:) consulta

(Gp:) petición

respuesta (Gp:) petición

(Gp:) petición

¡ Muy eficaz con multiprocesadores ! Soportados de dos formas: En el espacio del S.O. En el espacio del Usuario Biblioteca

edu.red

21 Threads ( "Linux" ) int __clone (int (*fn) (void *arg), void *child_stack, int flags, void *arg) (Gp:) Como fork sólo que crea un Thread "Específico de Linux" Thread soportado como tal por el S.O. (no portable)

(Gp:) Biblioteca pthread (API POSIX 1003.1c)

int pthread_create (pthread_t * thread, atributos, funcion, argumentos) pthread_t pthread_self (void) int pthread_exit (void *estado) int pthread_join (pthread_t thread, void **estado) …………………………………………… …………………………………………… ¿ fork + threads ?

edu.red

22 Threads ( Ejemplos de uso: tonto.c ) #include < pthread.h> #include < stdio.h> int main (int argc, char *argv[]){ pthread_t tA, tB; int datoA=0; datoB=0;

pthread_create(&tA, NULL, A, NULL); pthread_create(&tB, NULL, B, NULL); pthread_join (tA, NULL); pthread_join (tB, NULL); exit (0); } void *B (void *basura) { datoB = 2000; sleep (5); printf ("datoA=%dn", datoA); pthread_exit (NULL); } void *A (void *basura) { datoA = 1000; sleep (5); printf ("datoB=%dn", datoB); pthread_exit (NULL); } (Gp:) datoC=0; (Gp:) int datoC; (Gp:) int datoC; (Gp:) ?

edu.red

Threads ( Ejemplos de uso: cuentaPar.c ) cuentaPar.c: Número de apariciones de un número en un vector (Gp:) 6 2 0 7 4 9 3 4 9 8 0 6 7 9 6 0 6 7 9 8 6 2 5 2 6 4 7 9 3 5 2 1 7 3 2 6 6 4 4 0 (Gp:) const N = 40; objetivo = 6; numCPUs = 4; var vector array[1..N] of integer;

¿ Algoritmo paralelo ? (Gp:) T0 (Gp:) T1 (Gp:) T2 (Gp:) T3

(Gp:) 1 (Gp:) 3 (Gp:) 2 (Gp:) 2

(Gp:) + (Gp:) 8

23

edu.red

(Gp:) int longRodaja, numVecesLocal[MAX_ESCLAVOS], *vector;

void *esclavo (void *parametro) { ….. }

int main (int argc, char *argv[]) { int i, numVeces, cardinalidad = atoi (argv[1]); int numEsclavos = atoi (argv[2]); pthread_t pids[MAX_ESCLAVOS];

// Pedir memoria e inicializar vector

// Crear esclavos y esperar a que terminen su trabajo for (i = 0; i < numEsclavos; i++) pthread_create (&pids[i], NULL, esclavo, (void *) i); for (i = 0; i < numEsclavos; i++) pthread_join (pids[i], NULL);

// Sumar los valores de todos e informar del resultado numVeces = numVecesLocal[0]; for (i = 1; i < numEsclavos; i++) numVeces = numVeces + numVecesLocal[i]; printf ("Veces que aparece = %dn", numVeces); }

(Gp:) %cuentaPar 1000000 4

Threads ( Ejemplos de uso: cuentaPar.c ) 24

edu.red

// Variables globales int longRodaja, numVecesLocal[MAX_ESCLAVOS], *vector;

void *esclavo (void *parametro) { int yo, inicio, fin, i, j, numVeces;

yo = (int) parametro; inicio = yo * longRodaja; fin = inicio + longRodaja;

// Buscar en mi parte del vector numVeces = 0; for (i = inicio, i < fin; i++) if (vector[i] == NUM_BUSCADO) numVeces++; numVecesLocal[yo] = numVeces; pthread_exit (NULL); } 25 Threads ( Ejemplos de uso: cuentaPar.c )

edu.red

(Gp:) 5 (Gp:) 1,286 (Gp:) 4,26 (Gp:) 0,85 (Gp:) 6 (Gp:) 1,127 (Gp:) 4,86 (Gp:) 0,81 (Gp:) 7 (Gp:) 1,113 (Gp:) 4,92 (Gp:) 0,70 (Gp:) 8 (Gp:) 0,998 (Gp:) 5,49 (Gp:) 0,69

(Gp:) cuentaPar 400.000.000 1..8 // Recorriéndolo diez veces (Gp:) 2 Xeon E5520 Quad 2,26GHz . 8ML3 . 12GB . 500GB

Threads ( Ejemplos de uso: cuentaPar.c ) 26 (Gp:) Esclavos (Gp:) Tiempo (Gp:) Aceleración (Gp:) Eficiencia (Gp:) 1 (Gp:) 5,480 (Gp:) 2 (Gp:) 2,721 (Gp:) 2,01 (Gp:) 1,01 (Gp:) 4 (Gp:) 1,408 (Gp:) 3,89 (Gp:) 0,97 (Gp:) An = T1 / Tn (Gp:) En = An / n

edu.red

sortPar.c: Ordenar un vector en memoria (Gp:) 3 8 15 2 4 1 7 10 6 14 13 5 11 9 12 16 (Gp:) T0 (Gp:) T1 (Gp:) T2 (Gp:) T3

(Gp:) 2 3 8 15 1 4 7 10 5 6 13 14 9 11 12 16

(Gp:) ordenar

(Gp:) 1 2 3 4 7 8 10 15 5 6 9 11 12 13 14 16

(Gp:) T0 (Gp:) T2 (Gp:) mezclar

(Gp:) T0 (Gp:) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (Gp:) mezclar

Threads ( Ejemplos de uso: sortPar.c ) 27

edu.red

sortPar.c: Ordenar un vector en memoria [Refinamiento] (Gp:) A (Gp:) B (Gp:) C (Gp:) D (Gp:) E (Gp:) F (Gp:) G (Gp:) 0 (Gp:) 1 (Gp:) 2 (Gp:) 3 (Gp:) 0 (Gp:) 2 (Gp:) 0

esclavo (yo: integer);

ordenarRodaja(yo); case yo of 0: mezclar(A,B,E); mezclar(E,F,G); 1: ; 2: mezclar(C,D,F); 3: ; end; ? (Gp:) La mezcla es destructiva => vector auxiliar (Gp:) Va (Gp:) Va (Gp:) Vb (Gp:) Va

Mezclar requiere haber ordenado . => semáforos Threads ( Ejemplos de uso: sortPar.c ) 28 sem_init sem_wait sem_post

edu.red

#define MAX_ENTERO 10000 #define MAX_ESCLAVOS 4 // Solo funciona con 4 esclavos

//————– VARIABLES GLOBALES ——————————- int cardinalidad, longRodaja; int *vector, *vectorBis; sem_t S1a0, S3a2, S2a0;

void imprimir (int *vector) { int i;

printf ("Contenido del vectorn"); printf ("====================n"); for (i=0; i< cardinalidad; i++) { printf ("%6d ", vector[i]); if ((i%10) == 0) printf ("n"); } printf ("n"); }

void mezclar (int i, int longRodaja, int *vOrg, int *vDst) { int iDst, iTope, j, jTope;

iTope = i + longRodaja; j = iTope; jTope = j + longRodaja; for (iDst = i; iDst < jTope; iDst++) { if (i == iTope ) vDst[iDst] = vOrg[j++]; else if (j == jTope ) vDst[iDst] = vOrg[i++]; else if (vOrg[i] < vOrg[j]) vDst[iDst] = vOrg[i++]; else vDst[iDst] = vOrg[j++]; } } Threads ( Ejemplos de uso: sortPar.c ) 29

edu.red

void *esclavo(void *parametro) { int yo, inicio, fin, i, j, imenor, menor; int unCuarto, unMedio;

yo = (int) parametro; inicio = yo * longRodaja; fin = inicio + longRodaja; unMedio = cardinalidad / 2; unCuarto = cardinalidad / 4;

// Ordenar por insercion directa for (i = inicio; i < fin; i++) { imenor = i; menor = vector[i]; for (j = i; j < fin; j++) if (vector[j] < menor) { imenor = j; menor = vector[j]; } vector[imenor] = vector[i]; vector[i] = menor; }

// Fase de mezclas. Solo valida para 4 esclavos switch (yo) { case 0: sem_wait (&S1a0); mezclar(0, unCuarto, vector, vectorBis); sem_wait (&S2a0); mezclar(0, unMedio, vectorBis, vector); break; case 1: sem_post (&S1a0); break; case 2: sem_wait (&S3a2); mezclar(unMedio, unCuarto, vector, vectorBis); sem_post (&S2a0); break; case 3: sem_post (&S3a2); break; default: printf ("Errorn"); break; } pthread_exit(NULL); } Threads ( Ejemplos de uso: sortPar.c ) 30

edu.red

int main( int argc, char *argv[] ) { int i, numEsclavos; pthread_t pids[MAX_ESCLAVOS];

cardinalidad = atoi(argv[1]); numEsclavos = MAX_ESCLAVOS; longRodaja = cardinalidad / numEsclavos;

// Pedir memoria e inicializar el vector vector = malloc(cardinalidad * sizeof(int)); vectorBis = malloc(cardinalidad * sizeof(int)); for (i=0; i< cardinalidad; i++) vector[i] = random() % MAX_ENTERO; imprimir(vector);

// Inicializar semaforos para sincronizar sem_init (&S1a0, 0, 0); sem_init (&S3a2, 0, 0); sem_init (&S2a0, 0, 0);

// Crear esclavos y esperar a que terminen su trabajo for (i=0; i< numEsclavos; i++) pthread_create (&pids[i], NULL, esclavo, (void *) i); for (i=0; i< numEsclavos; i++) pthread_join (pids[i], NULL);

imprimir(vector); return (0); } sort 200000 => 8:350 sortPar 200000 => 2:100 Threads ( Ejemplos de uso: sortPar.c ) 31

edu.red

32 pthread_create pthread_join pthread_exit pthread_self Threads ( En el espacio de usuario ) (Gp:) El S.O. no los soporta Cambio contexto rápido Distintos planificadores

(Gp:) read, . ¡ Bloqueantes ! Falta de página ¡Planificación expulsora!

edu.red

33 Threads ( En el espacio del S.O. ) (Gp:) ?

edu.red

34 Comunicación entre Procesos Los procesos cooperantes necesitan mecanismos para sincronizarse y comunicarse información de forma segura Sincronización ? Ordenación temporal de la ejecución de procesos A antes que B (Gp:) Canal de Panamá

Tortilla de patatas Batir Pelar Pelar Huevos Cebollas Patatas Mezclar, Añadir Sal y Freir Comunicación ? Paso de información entre tareas Síncrona o Asíncrona Filtros Unix: who | wc | sed -e 's/ [ ]*/:/g' | cut -d: -f2

edu.red

35 Condiciones de Carrera La falta de sincronismo entre procesos cooperantes da problemas Canal de Panamá ? Barco encallado Tortilla de Patatas ? No hay quien se la coma Uso de datos / recursos comunes ? Inconsistencia El empresario y los taxistas: (Gp:) ¡Que buen negocio!

(Gp:) ¡Me tangan!

edu.red

36 Condiciones de Carrera (Modelización con threads) Ingreso de Taxista 1 = 80729 Ingreso de Taxista 2 = 80618 Total recaudacion = 161096 (Gp:) + (Gp:) 161347

(Gp:) int cuenta; void *taxista(void *parametro) { ….. } int main( int argc, char *argv[] ) { int i, numEsclavos; pthread_t pids[MAX_ESCLAVOS];

numEsclavos = atoi(argv[1]); cuenta = 0; // Crear esclavos y esperar a que terminen su trabajo for (i=0; i< numEsclavos; i++) pthread_create (&pids[i], NULL, taxista, (void *) i); for (i=0; i< numEsclavos; i++) pthread_join (pids[i], NULL); printf ("Total recaudacion = %dn", cuenta); return (0); }

edu.red

37 (Gp:) Ingreso

Condiciones de Carrera (Modelización con threads) void *taxista (void *parametro) { // Variables recaudacion = 0; mio = 0; do { espera = random() % MAX_ESPERA; for (i=1; i< espera; i++); importe := random (maxImporte); mio := mio + (importe / RATIO_TAXISTA); cuenta := cuenta + importe – (importe / RATIO_TAXISTA); recaudacion := recaudacion + importe; } while (mio < SUELDO_DIA); printf ("Ingreso de Taxista %d = %dn", yo, recaudacion – mio); pthread_exit (NULL); } (Gp:) Hacer Carrera

(Gp:) Buscar Cliente

edu.red

38 Condiciones de Carrera (Modelización con threads) (Gp:) Threads (Gp:) pc1:4Cores (Gp:) pc9:8Cores (Gp:) 2 (Gp:) 4 (Gp:) 8 (Gp:) 16 (Gp:) 32 (Gp:) Fallos x 1.000 (Gp:) 7 (Gp:) 64 (Gp:) 230 (Gp:) 533 (Gp:) 830 (Gp:) 207 (Gp:) 926 (Gp:) 1.000 (Gp:) 1.000 (Gp:) 1.000

edu.red

39 3: cuenta := cuenta + importe Condiciones de Carrera (El problema) (Gp:) 3.1: PUSH importe 3.2: PUSH cuenta 3.3: ADDP 3.4: POP cuenta

3.1, 3.2 (Gp:) T1 (Gp:) T2 (Gp:) 5.000 (Gp:) cuenta (Gp:) 10.000 (Gp:) T1.importe

(Gp:) 3.3 (Gp:) 5.000 (Gp:) 10.000 (Gp:) T1.SP

3.1, 3.2 (Gp:) 1.500 (Gp:) T2.importe (Gp:) 3.3 (Gp:) 5.000 (Gp:) 1.500 (Gp:) T2.SP

3.3, 3.4 (Gp:) 15.000

(Gp:) 15.000 (Gp:) cuenta

3.3, 3.4 (Gp:) 6.500 (Gp:) cuenta (Gp:) 6.500

¿problema?

edu.red

40 Exclusión mutua y Región crítica (La solución) (Gp:) RC (Gp:) RC

(Gp:) Aquí como máximo un Pi

(Gp:) Exclusión Mutua

(Gp:) Integridad Datos Comunes

(Gp:) Aquí cero, uno o más Pi

Los Pi indicarán cuándo EntranEnRC y cuándo SalenDeRC

edu.red

41 Exclusión mutua y Región crítica (La solución) EntrarEnRC; cuenta := cuenta + importe – (importe div ratioTaxista); SalirDeRC; REQUISITOS En una misma Región Crítica no más de un proceso Sin supuestos: #µP, #Pi, velocidades relativas, ….. Ningún Pi fuera de su Región Crítica bloqueará a otros Pj Decisión de quién entra a una Región Crítica en un tiempo finito

edu.red

42 Implementación de la Exclusión Mutua Mecanismos: Inhibición de interrupciones . Semáforos Cerrojos (espera activa) . Monitores (Gp:) Hw (Gp:) Sw

(Gp:) Lenguaje (Gp:) S.O.

Inhibición de interrupciones Taxistas InhibirInterrupciones cuenta := cuenta + importe PermitirInterrupciones RC muy corta o pueden perderse interrupciones Exclusión total vs parcial DirecciónGeneralDeTráfico repeat aguardarAgazapados y ¡foto! InhibirInterrupciones numeroMultas++ PermitirInterrupciones until cubiertoCupo Sólo válido en monoprocesador Peligroso en manos del usuario Útil dentro del propio S.O.

edu.red

43 Implementación de la Exclusión Mutua ( Cerrojos ) Una variable "cerrojo" por cada RC distinta que indica Libre/Ocupada (Gp:) Taxistas Entrar (RCTaxistas) cuenta := cuenta + importe Salir (RCTaxistas) (Gp:) Guardia Civil Entrar (RCDGT) numeroMultas++ Salir (RCDGT)

(Gp:) while RCT = ocupada do null; RCT := ocupada cuenta := cuenta + importe; RCT := libre

(Gp:) entrar tst.b RCT bnz entrar move.b #$FF,RCT push importe push cuenta addp pop cuenta salir move.b #$00,RCT

RCT dc.b 0

¡ No funciona !

edu.red

44 Implementación de la Exclusión Mutua ( El cerrojo falla ) (Gp:) T1 (Gp:) T2 (Gp:) 00 (Gp:) RCT

—————- —————- entrar tst.b RCT —————- —————- tst.b RCT bnz entrar move.b #$FF,RCT —————- —————- (Gp:) T1.SR (Gp:) Z (Gp:) 1

(Gp:) FF (Gp:) RCT

(Gp:) T2 dentro RCT

bnz entrar move.b #$FF,RCT —————- —————- —————- —————- (Gp:) FF (Gp:) RCT

¡¡ T1 también dentro RCT !!

edu.red

45 Implementación de la Exclusión Mutua ( Un cerrojo seguro? ) (Gp:) El Hw ayuda con una instrucción atómica que consulta y cambia valor (Gp:) tas.b cerrojo, valor

(Gp:) tst.b cerrojo move.b valor,cerrojo

Algoritmos: Dekker, Dijkstra, Knuth, Peterson, ……. (Gp:) entrar tas.b RCT,#$FF bnz entrar push importe push cuenta addp pop cuenta salir move.b #$00,RCT

RCT dc.b 0

(Gp:) F.R.

¿Habrá problemas? (Gp:) No funciona en multiprocesador ya que TAS es ininterrumpible dentro de un procesador, pero supone dos accesos al bus: 1 Lectura del cerrojo 2 Modificación del cerrojo (Gp:) ¡SI!

edu.red

46 Implementación de la Exclusión Mutua ( Un cerrojo seguro! ) T1 T2 (Gp:) 00 (Gp:) RCT

—————- —————- tas.b RCT,#$FF —————- —————- tas.b RCT,#$FF bnz entrar (Gp:) T1.SR (Gp:) Z (Gp:) 1

(Gp:) FF (Gp:) RCT

(Gp:) FF (Gp:) RCT

bnz entrar ————- ————- ————- ————- T1 en RCT (Gp:) FF (Gp:) RCT

T2 no puede entrar en RC mientras está T1 (Gp:) tas.b RCT,#$FF bnz entrar

edu.red

47 Implementación de la Exclusión Mutua ( TAS todavía falla! ) TAS ? PedirBus, Leer, PedirBus, Escribir (Gp:) ?P1 ? T1 PB, L1, PB, E1 (Gp:) ?P2 ? T2 PB, L2, PB, E2

(Gp:) ???

(Gp:) ?P1 (Gp:) ?P2 (Gp:) RCT

(Gp:) L1, E1, L2, E2 T1 T2

(Gp:) L2, E2, L1, E1 T2 T1

(Gp:) L1, L2, E1, E2 T1 T2

tas.b RCT,#$FF bnz entrar (Gp:) PH

tasl.b RCT,#$FF bnz entrar ——————— ——————— ¡ Todavía dos problemas ! Espera Activa Inversión de prioridades (Gp:) PL

(Gp:) deadLock

¿ Qué hacer ? (Gp:) TASL "TAS with Lock" ? BusLock, Leer, Escribir, BusRelease (Gp:) ( El Hw nos ayuda )

edu.red

48 Implementación de la Exclusión Mutua ( RC POSIX ) int pthread_mutex_lock (pthread_mutex_t *regionCritica) int pthread_mutex_unlock (pthread_mutex_t *regionCritica) ¿Posible implementación (sin espera activa)? type pthread_mutext_t is record libre : BOOLEAN; cola : unaCola; end record; (Gp:) F (Gp:) RCT (Gp:) Pi (Gp:) Pj

lock (RCT): inhibir interrupciones salvarEstado(ejecutandose) if RCT.libre then RCT.libre = FALSE else meter (ejecutandose, RCT); ejecutandose = planificar(); recuperarEstado(ejecutandose) rte /*Se habilitan interrupciones*/ (Gp:) Multiprocesador (Gp:) ?

tasl (Gp:) ¡ Ojo !

edu.red

49 Implementación de la Exclusión Mutua ( Semáforos ) Soportado por el S.O. garantiza exclusión mutua sin espera activa type Semaforos is private; Inicializar (S: Semaforos; Valor: NATURAL); Bajar (S); — Puede bloquear al proceso (Si Valor = 0) Subir (S); — Puede desbloquear a UN proceso (Gp:) Operaciones Atómicas

Dar soporte a RC con semáforos es fácil: Inicializar (S_RCT, 1) Inicializar (S_RCGC, 1) ————— ————— Bajar (S_RCT) Bajar (S_RCGC) Cuenta := Cuenta + Importe numeroMultas++ Subir (S_RCT) Subir (S_RCGC) ————— —————

edu.red

50 Implementación de la Exclusión Mutua ( Semáforos ) Precisando la semántica: P.Bajar (S) ? IF Valor(S) > 0 THEN Valor (P.Bajar(S)) = Valor(S) – 1 ELSE P deja UCP y se bloquea esperando P'.Subir(S)

P.Subir(S) ? IF Hay_algun_Pi_esperando_en (S) THEN Sacar a uno de ellos de espera INDETERMINISMO Proceso continuado Proceso que coge UCP JUSTICIA ELSE Valor (P.Subir(S)) = Valor (S) + 1

edu.red

51 Implementación de la Exclusión Mutua ( Semáforos ) private type Semaforos is record valor : NATURAL; cola : unaCola; end record; procedure Inicializar (S : out Semaforos; valor : NATURAL) is begin S.valor := valor; end Inicializar; Esbozo de implementación: (Gp:) 0 (Gp:) S (Gp:) Pi (Gp:) Pk (Gp:) Pj

(Gp:) ¿Dónde están los semáforos?

Hacen falta operaciones del estilo: crear, conectarse, destruir (Gp:) Exclusión mutua, Salvado estado Pi

(Gp:) Dispatcher

edu.red

52 Implementación de la Exclusión Mutua ( Semáforos ) procedure Bajar (S: in out Semaforos) is begin if S.valor = 0 then encolar (ejecutandose, S.cola); planificar; else S.valor := S.valor – 1; endif; end Bajar; procedure Subir (S: in out Semaforos) is begin if S.cola.primero /= 0 then encolar (sacarProceso(S.cola), preparados); planificar; else S.valor := S.valor + 1; endif; end Subir;

edu.red

53 Implementación de la Exclusión Mutua ( Semáforos POSIX ) int sem_init (sem_t *S, int global, unsigned int valor) int sem_wait (sem_t *S) int sem_post (sem_t *S) int sem_destroy (sem_t *S)

edu.red

54 Paso de mensajes Debilidades del Sincronismo + Memoria Común: Primitivas de bajo nivel (Inhibir Interrupciones, TASL, Semáforos) Inviable en sistemas débilmente acoplados sin memoria común (Gp:) Solución: Envío y recepción de mensajes (Gp:) Porg (Gp:) Pdst (Gp:) Enviar (Pdst, msj) (Gp:) Recibir (Porg, msj)

—– —– —– (Gp:) Escribe

11 —– —– —– —– —– —– 11 (Gp:) Lee

Primera aproximación a la sintaxis: void enviar ( int Pdestino, void recibir ( int Porigen, char * msj ); char * msj ); ¿Puede fallar enviar/recibir? (Gp:) ? (Gp:) ?

(Gp:) int (Gp:) int

edu.red

Paso de mensajes ( Ejemplos de uso: cuentaParMsj.c ) ¿Cómo podría ser cuentaPar.c si no hay memoria común? (Gp:) 1 (Gp:) 3 (Gp:) 2 (Gp:) 2 (Gp:) 6 2 0 . (Gp:) 0 6 7 . (Gp:) 6 2 5 . (Gp:) 2 1 7 . (Gp:) + (Gp:) 8

(Gp:) esclavo1 (Gp:) esclavo2 (Gp:) esclavo3 (Gp:) esclavo4

(Gp:) maestro (Gp:) 6 2 0 . (Gp:) 0 6 7 . (Gp:) 6 2 5 . (Gp:) 2 1 7 . (Gp:) El vector lo tiene un proceso "maestro"

El maestro: reparte "envía" trabajo a los "esclavos" y recoge "recibe" resultados (Gp:) 6 2 0 . (Gp:) 0 6 7 . (Gp:) 6 2 5 . (Gp:) 2 1 7 .

(Gp:) 1 (Gp:) 3 (Gp:) 2 (Gp:) 2

55

edu.red

56 Paso de mensajes ( Ejemplos de uso: cuentaParMsj.c ) (Gp:) #define longRodaja (N/4) int vector[N], iRodaja; int veces, vecesLocal;

// Repartir trabajo iRodaja = 0; for e in 1..4 { enviar (e, &vector[iRodaja], longRodaja); iRodaja += longRodaja; }

// Recoger resultados veces = 0; for e in 1..4 { recibir (e, &vecesLocal, 1); veces += vecesLocal; } (Gp:) #define longRodaja (N/4)

int rodaja[longRodaja]; int veces;

recibir (0, rodaja, longRodaja); veces = contarEn (rodaja); enviar (0, &veces, 1); (Gp:) maestro (Gp:) esclavo

edu.red

57 Paso de mensajes (muchas semánticas) (Gp:) —– —– —– (Gp:) rec (Po, msj) (Gp:) —– —– —– (Gp:) —– —– —– (Gp:) env (Pd, msj) (Gp:) —– —– —–

(Gp:) Pd

¿Bloqueo? (Gp:) El bloqueo dependerá de la ? | ? de mensajes

? msj ? Se le entrega a Pd y continua (Gp:) ? msj ? Se bloquea a Pd hasta

(Gp:) No siempre

(Gp:) Tiempo Real Tolerancia a Fallos

Bloquear Bloquear un máximo No Bloquear (Gp:) int recibir ( int Porg, char * msj, int TmaxEsp)

? 7 (Gp:) 0

(Gp:) ?

(Gp:) ?

(Gp:) Po

¿Bloqueo? (Gp:) ¿Recibió Pd? (Gp:) Po

Independencia del enlace de comunicación

edu.red

58 Paso de mensajes (Cuestiones de Diseño) Mensajes de longitud fija vs variable Capacidad de almacenamiento 0 .. ? Envío por copia vs referencia Comunicación Directa vs Indirecta (Gp:) Pi B Pj (Gp:) Pi Pj

(Gp:) Simétrica vs Asimétrica

(Gp:) Unidireccional vs Bidireccional

edu.red

59 Paso de mensajes (Mensajes de longitud fija vs variable) Longitud Fija El S.O. siempre envía el total (Gp:) La aplicación distingue distintos msj.

Simplifica la gestión de la capacidad de almacenamiento del canal Longitud Variable El S.O. envía lo que diga la aplicación (Gp:) ¿Cómo?

(Gp:) 110 (Gp:) Mensaje de 110 bytes (Gp:) En el propio mensaje

(Gp:) enviar (Pdest, msj, 110) (Gp:) En la llamada

edu.red

60 Paso de mensajes (Mensajes de longitud fija vs variable) (Gp:) MINIX 3 (Gp:) typedef struct { int m_source; int m_type; union { mess_1 m_m1; mess_2 m_m2; mess_3 m_m3; mess_4 m_m4; mess_5 m_m5; mess_7 m_m7; mess_8 m_m8; } m_u; } message;

(Gp:) m_source (Gp:) m_type (Gp:) m1_i1 (Gp:) m1_i2 (Gp:) m1_i3 (Gp:) m1_p1 (Gp:) m1_p2 (Gp:) m1_p3 (Gp:) m_source (Gp:) m_type (Gp:) m2_i1 (Gp:) m2_i2 (Gp:) m2_i3 (Gp:) m2_l1 (Gp:) m2_l2 (Gp:) m2_p1 (Gp:) m_source (Gp:) m_type (Gp:) m3_i1 (Gp:) m3_i2 (Gp:) m3_p1 (Gp:) m3_ca1 (Gp:) m_source (Gp:) m_type (Gp:) m4_i1 (Gp:) m4_i2 (Gp:) m4_i3 (Gp:) m4_i4 (Gp:) m4_i5

Práctica 4: Nueva llamada SO Proceso70.if (proceso_vivo(84) (Gp:) 70 (Gp:) 57 (Gp:) 84

(Gp:) # Llamada 57

edu.red

61 Paso de mensajes (Capacidad de almacenamiento 0..?) (Gp:) Ilimitada (?) (Gp:) Po (Gp:) Pd

(Gp:) Po (Gp:) Pd

¡Nunca Bloqueo! (Gp:) Limitada (8) (Gp:) Po (Gp:) Pd

(Gp:) Po (Gp:) Pd

Hueco ? Sin Bloqueo ¡No hay Hueco! (Gp:) Bloqueo Sin Bloqueo Estado = Lleno

(Gp:) Comunicación Asíncrona

(Gp:) Nula (0) (Gp:) Po (Gp:) Pd

¡Siempre Bloqueo! (Gp:) Po (Gp:) Pd

Espera a Pd.recibir (Gp:) Po (Gp:) Pd (Gp:) Cita "Rendez-vous"

(Gp:) Po (Gp:) Pd

(Gp:) Comunicación Síncrona

(Gp:) Po sabe que Pd recibió

(Gp:) ¿Y aquí?

edu.red

62 (Gp:) Po (Gp:) Pd

Paso de mensajes (Envío por copia vs referencia) (Gp:) Escribir —– —– —–

(Gp:) env (Pd, msj)

(Gp:) 1

(Gp:) rec (Po, msj)

(Gp:) 2

¡ 2 copias extra por cada envío/recepción ! (Gp:) Leer —– —– —–

(Gp:) Envío por referencia (Gp:) Po (Gp:) Pd

(Gp:) pedirBuffer

(Gp:) Escribir —– —– —–

(Gp:) env (Pd, msj)

(Gp:) rec (Po, msj)

Leer —– —– —– (Gp:) liberarBuffer

Complejidad pedir/liberar Buffer ¿Y si no hay memoria común? ¿Seguridad?

edu.red

63 Paso de mensajes (Comunicación Directa) (Gp:) Indicación explícita (Gp:) A qué proceso se desea enviar De qué proceso se desea recibir

(Gp:) Cliente (Gp:) Servidor

(Gp:) ¿15.731 es primo?

(Gp:) SÍ

repeat repeat read (msjp.num); recibir ( Pc, &msjp); enviar (Ps, &msjp); enviar ( Pc, recibir (Ps, &msjr); respuesta(msjp)) imprimir (msjr.esPrimo) forever forever (Gp:) Simétrica (Gp:) Simétrica

edu.red

64 Paso de mensajes (Comunicación Directa "Características") (Gp:) Creación automática del enlace Po Pd

Necesidad de conocer los Pid's de los procesos De Pi a Pj SÓLO un enlace en cada sentido (Gp:) Cliente (Gp:) Servidor (Gp:) esPrimo? (Gp:) Hora?

(Gp:) Cliente (Gp:) Servidor

? (Gp:) 15.731 (Gp:) 0 (Gp:) 1 (Gp:) Tipo de mensaje

¿Todo resuelto? (Gp:) Cliente (Gp:) Servidor

P P P P P P P H Un enlace asocia SÓLO a dos procesos

edu.red

65 Paso de mensajes (Un enlace asocia SÓLO a dos procesos) (Gp:) C1 (Gp:) C2 (Gp:) S

(Gp:) C1 (Gp:) C2 (Gp:) S

(Gp:) repeat if recibir (PC1, &msjp ) then enviar (PC1, respuesta (msjp)); elsif recibir (PC2, &msjp ) then enviar (PC2, respuesta (msjp)); forever (Gp:) Servidor

Inanición Espera Activa (Gp:) , 1 (Gp:) , 1 (Gp:) Mitigada?

50 Clientes???? ! Demasiadas pegas ¡

edu.red

66 Paso de mensajes (Comunicación Directa Asimétrica) Mejor admitir un recibir de cualquier proceso (no uno concreto) (Gp:) C1 (Gp:) C2 (Gp:) S

(Gp:) int recibir (char * msj) (Gp:) Pid del proceso remitente

(Gp:) int recibir (int * remitente, char * msj) (Gp:) equivalentes

(Gp:) repeat remitente := recibir (&msjp); enviar (remitente, respuesta (msjp)); forever (Gp:) Servidor

¿Más de un servidor? (Gp:) int enviar (char * msj) (Gp:) Pid del proceso que recibió???

(Gp:) C (Gp:) S1 (Gp:) S2

edu.red

67 Paso de mensajes (Comunicación Indirecta) (Gp:) bPeti (Gp:) PC (Gp:) PS (Gp:) 1 ? 1

(Gp:) bPeti (Gp:) PC (Gp:) PS1 (Gp:) PSm (Gp:) 1 ? M

(Gp:) bPeti (Gp:) PC1 (Gp:) PCn (Gp:) PS1 (Gp:) PSm (Gp:) N ? M

¿Quién recibe? Indeterminismo Justicia Integridad (Gp:) bPeti (Gp:) PC1 (Gp:) PCn (Gp:) PS (Gp:) N ? 1

¿De quién recibí? (Gp:) PCn

enviar (buzon, msj) recibir (buzon, msj) (Gp:) int recibir (buzon, msj) (Gp:) PCn

edu.red

68 Paso de mensajes (Comunicación Indirecta) Los enlaces pueden ser Unidireccionales o Bidireccionales (Gp:) PC (Gp:) PS

¿ Problemas ? (Gp:) PC1 (Gp:) PS (Gp:) PC2

¿ Y aquí ? Lo normal Unidireccionales: (Gp:) bPeti (Gp:) PC (Gp:) PS1 (Gp:) PS2 (Gp:) bResp

(Gp:) ¿ Código del Cliente y de los Servidores ?

Lo más general: (Gp:) B1 (Gp:) P2 (Gp:) P4 (Gp:) P5 (Gp:) B2 (Gp:) P3 (Gp:) P1

Varios Procesos Varios Buzones Todo dinámico

edu.red

69 Paso de mensajes (Comunicación Indirecta) (Gp:) type Buzones is private; function Crear (nombreB: Nombres ) return Buzones; function Conectarse (nombreB: Nombres) return Buzones; procedure Enviar (b: in out Buzones; msj: Mensajes); procedure Recibir (b: in out Buzones; msj: out Mensajes); procedure Destruir (b: in out Buzones); (Gp:) Un modelo:

(Gp:) Capacidad

(Gp:) * (Gp:) * (Gp:) ? Propietario (Gp:) *

Excepción ? buzonInexistente, … ¡ Problemática Destrucción ! (Gp:) Mensajes en el buzón Procesos bloqueados Referencias a buzones destruidos

(Gp:) mqd_t mq_open (const char *name, int oflag, .) int mq_send (mqd_t mqid, const char *msgptr, size_t msgsz, unsigned msgprio) ssize_t mq_receive (mqd_t msid, char *msgp, size_t msgsz, unsigne *msgprio) int mq_close (mqd_t mqid) (Gp:) POSIX

edu.red

70 Planificación de Procesos ( Criterios ) Planificar ? Elegir el siguiente Pi a ejecutar (Gp:) JUSTICIA EFICIENCIA RENDIMIENTO MINIMIZAR TIEMPOS (Gp:) Criterios

(Gp:) Carga (Gp:) Sin CPU (Gp:) Ejecutándose (Gp:) Pi

(Gp:) Tiempo de Retorno

(Gp:) CPU

(Gp:) Tiempo útil

(Gp:) Tiempo inútil

(Gp:) Tiempo de Espera

¿Tiempo de Respuesta? (Gp:) Pi

(Gp:) < cr>

Criterios difícilmente alcanzables: Favorecer Pi ? Perjudicar Pj

edu.red

71 Planificación de Procesos ( PCPU vs PE/S ) (Gp:) PCPU

(Gp:) PE/S

(Gp:) Periodos largos de CPU

(Gp:) Periodos cortos de CPU

? ¿Cómo reconocerlos? (Gp:) Abandona voluntariamente la UCP

edu.red

72 Sistemas Batch No expulsores o expulsores con un quantum grande Reducen cambios de contexto y mejoran el rendimiento Por niveles, Primero en llegar primero en servir FCFS, Más corto el siguiente SJF, Tiempo restante menor SRTN Sistemas interactivos Expulsores: evita la monopolización de la CPU Round-Robin, prioridades, múltiples colas, Más corto el siguiente SPN (envejecimiento) Sistemas de tiempo real Monotónico en frecuencia Deadline más próximo el siguiente Planificación de Procesos ( Políticas )

edu.red

73 Planificación de Procesos ( Por niveles ) (Gp:) Planificación a medio plazo Memoria (Gp:) Planificación a corto plazo CPU (Gp:) CPU (Gp:) IT2 (Gp:) T2 (Gp:) T3 (Gp:) T5 (Gp:) T1, T2, T3, T4, T5, T6 (Gp:) S.O. (Gp:) Entrada al sistema

(Gp:) frecuencia alta

(Gp:) frecuencia baja

edu.red

74 Planificación de Procesos ( Primero en llegar FCFS ) Sólo cuando un proceso abandona voluntariamente la CPU, la misma se asigna al proceso que lleva más tiempo preparado (FIFO) D C (Gp:) A

(Gp:) B

(Gp:) A (Gp:) D (Gp:) B (Gp:) C

(Gp:) D (Gp:) B (Gp:) C (Gp:) A (Gp:) E/S

Sencillo, pero ? Ausencia de política (Gp:) D (Gp:) C (Gp:) B (Gp:) A (Gp:) 4 4 4 8 (Gp:) D (Gp:) C (Gp:) B (Gp:) A (Gp:) 8 4 4 4

(Gp:) Tesp (Gp:) Tret

(Gp:) 9 (Gp:) 14

(Gp:) Tesp (Gp:) Tret

(Gp:) 6 (Gp:) 11

"Efecto convoy" (Gp:) {PE/S}n (Gp:) PUCP

(Gp:) PE/S (Gp:) {PE/S}n-1 (Gp:) PUCP (Gp:) E/S (Gp:) T >>

(Gp:) T <

edu.red

75 Planificación de Procesos ( Efecto convoy ) PUCP = {10UCP + 2E/S}* PE/S = {1UCP + 2 E/S}* (Gp:) PUCP (Gp:) PE/S

CPU al 100%, pero tan sólo 30 unidades de tiempo en E/S CPU al 100% y además, 55 unidades de tiempo en E/S (Gp:) PUCP (Gp:) PE/S (Gp:) ??

edu.red

76 Planificación de Procesos ( El más corto primero SJF ) (Gp:) Objetivo: Minimizar Tesp/ret

(Gp:) 8 (Gp:) 5 (Gp:) 4 (Gp:) 3

(Gp:) CPU

3 4 5 8 ¿Óptimo? (Gp:) ¿Dónde esperan los procesos?

(Gp:) CPU (Gp:) preparados

¿Aplicable SJF en planificación a largo y a corto plazo? (Gp:) ¿Más corto?

Tiempo total de CPU Lo declara el usuario Si engaña ? KILL (Gp:) ¿Más corto?

(Gp:) Sistemas interactivos

(Gp:) Contraejemplo (Gp:) 0 1 2 3 4 (Gp:) A(2) B(4) (Gp:) C(1) D(1) E(1)

edu.red

77 Variante expulsora del SJF. Cuando llega un trabajo nuevo, comparar su petición de tiempo con el tiempo que le queda al actual. Seleccionar el menor. Favorece a los trabajos nuevos 0 1 2 3 4 5 6 7 A(2) B(4) C(1) D(1) E(1) ¿Tiempo medio de espera? Planificación de Procesos ( Tiempo restante menor SRTN )

edu.red

78 Planificación de Procesos (Round Robin) "Todos iguales": Turno Rotatorio o Rodajas de Tiempo A cada Pi que pasa a ejecución se le dá una rodaja "cuanto" de tiempo (Gp:) La consume totalmente y se le expulsa (Gp:) Pi (Gp:) rodaja

(Gp:) La usa parcialmente y abandona voluntariamente la UCP (Gp:) Pi (Gp:) sleep, wait, exit

Política FIFO de gestión de la cola de preparados Dos cuestiones de diseño: ¿Cómo elegir el tamaño de la rodaja? ¿Cómo determinar el fin de rodaja? Ley del 80%

edu.red

79 Planificación de Procesos (Round Robin) ¿Cómo elegir el tamaño de la rodaja? Sea Tcc = 5 mseg (mucho) Rodaja pequeña 20 mseg => Burocracia del 20% Rodaja grande 500 mseg => Burocracia del 1% (Gp:) UCP útil

(Gp:) Respuesta lenta a usuarios interactivos

(Gp:) ¿Degenera en FCFS?

(Gp:) Mejor interactividad

(Gp:) Ejemplo: P1, P2, P3 => 24, 3 y 3. Rodajas 4 vs 12 y Tcc = 0,5

P1 P2 P3 P1 (Gp:) P1 (Gp:) P1 (Gp:) P1 (Gp:) P1 (Gp:) 33,5

(Gp:) P1 (Gp:) P2 (Gp:) P3 (Gp:) P1 (Gp:) 31,5

Valores comunes: 20..50 mseg

edu.red

80 Planificación de Procesos (Round Robin) ¿Cómo determinar el fin de rodaja? Una interrupción periódica (Gp:) P1

(Gp:) P2

(Gp:) P3

(Gp:) P4

(Gp:) sleep

(Gp:) ¿Somos justos con P3?

(Gp:) ¿viable?

F(int) en 68901 [1µseg..20mseg] Dar 2 rodajas Resetear interrupción Sumar ticks de una interrupción más frecuente (Gp:) P1 (Gp:) P2 (Gp:) sleep (Gp:) P3 (Gp:) P4

edu.red

81 Planificación de Procesos (Prioridades) "Unos más importantes que otros": Cada Pi prioridad explícita (Gp:) 0 N N 0 (Gp:) mín (Gp:) máx

(Gp:) expulsora (Gp:) P3 (Gp:) P7 (Gp:) P1

UCP siempre ejecuta Pi más prioritario UCP libre ? ejecutar Pi más prioritario Igualdad de prioridad ? FCFS, Round Robin Prioridades estáticas vs dinámicas (Gp:) Sencillo pero inanición

(Gp:) P3 (Gp:) P7 (Gp:) P1 (Gp:) P9

(Gp:) ¿ tiempo real ?

(Gp:) no expulsora (Gp:) P3 (Gp:) P7 (Gp:) P1

edu.red

82 Planificación de Procesos (Prioridades dinámicas) Evitar la inanición: Disminuir la prioridad a medida que se usa la UCP Aumentar la prioridad si se está tiempo en preparados ¿ Favorece a los trabajos cortos ? (Gp:) PE/S vs PUCP

Favorece a los Pi ligados a E/S ¿Cuáles son PE/S? ¿Todo el tiempo será PE/S? (Gp:) PE/S aquellos que usen una parte menor de la rodaja de UCP

Ejemplo con rodajas de 100 mseg: P1 usa 2 mseg de UCP ? PE/S P2 usa 25 mseg de UCP ? PUCP (Gp:) Prio (P1) = 100/2 = 50 Prio (P2) = 100/25 = 4

¿Rango de prioridades [0..N]? (Gp:) Estáticas muy bajo ? 16 Dinámicas muy variable

edu.red

83 Planificación de Procesos (Múltiples colas) "Mezcla de políticas": Cada Pi asociado a una cola de forma estática (Gp:) Prioridad (Gp:) 3 (Gp:) 2 (Gp:) 1 (Gp:) 0

(Gp:) FCFS

(Gp:) Round Robin

(Gp:) Quantum (Gp:) 4 (Gp:) 8 (Gp:) 16

Dos elecciones: Seleccionar cola Seleccionar proceso dentro de la cola (Gp:) ¿Expulsora?

edu.red

84 Planificación de Procesos (Múltiples colas realimentadas) "Mezcla de políticas": Cada Pi asociado a una cola de forma dinámica Menos Cambios de Contexto (Gp:) Prioridad (Gp:) 4 (Gp:) 3 (Gp:) 2 (Gp:) 1 (Gp:) 0

(Gp:) 1 (Gp:) + Rodajas Variables

2 4 8 16 Rodajas para Pi ? 1, 2, 4, 8, 16 Favorecer selectivamente PE/S (Gp:) Prioridad (Gp:) 3 Terminal 2 E/S 1 Rodaja corta 0 Rodaja larga

Consumir rodajas: Bajar de prioridad

edu.red

85 Planificación de Procesos (MINIX 3) (Gp:) /usr/src/kernel/proc.h

(Gp:) Pi

(Gp:) SI consumió su rodaja Nueva rodaja Prioridad++ ¡Menor! Encolar_Al_Final SINO Encolar_Al_Principio (Gp:) sched

(Gp:) Preparados (Gp:) MaxPrioridad (Gp:) MinPrioridad

(Gp:) RoundRobin

(Gp:) proc[log].p_nextready

edu.red

86 Planificación de Procesos ( Pi más corto siguiente SPN ) (Gp:) CPU (Gp:) preparados (Gp:) ¿Más corto? (Gp:) ¿Más corto? (Gp:) SJF (Gp:) SPN

(Gp:) Tiempo de próxima posesión de UCP

? (Gp:) ¿Predicción? (?i) ?

?i+1 = F (ti, ?i) ?i+1 = ? ti + (1- ?) ?i y ? = 1/2 Predicción (Gp:) ?i ? (Gp:) ti ?

10 6 8 4 (Gp:) 6 (Gp:) 6 (Gp:) 6 (Gp:) 4 (Gp:) 5 (Gp:) 13 (Gp:) 9 (Gp:) 13 (Gp:) 11 (Gp:) 13 (Gp:) 12

edu.red

87 Dado m eventos periódicos evento i ocurre en el periodo Pi y precisa Ci segundos El sistema es planificable si Hard real time vs Soft real time

Eventos: periódicos vs aperiódicos (Leer las secciones 7.4.2, 7.4.3 y 7.4.4) Planificación de Procesos ( Sistemas de Tiempo Real )

edu.red

88 Separar qué se puede hacer de cómo hacerlo Un proceso puede saber cuáles de sus threads hijos son los más importantes y asignarles prioridad

Algoritmo de planificación parametrizado Mecanismo en el kernel

Los procesos de usuario ponen el valor de los parámetros Los procesos de usuario indican la política

Planificación de Procesos ( Política vs Mecanismo ) pthread_attr_setschedpolicy(.) => FIFO, RR, OTHERS

edu.red

89 Quantum por proceso de 50 mseg Cada thread ejecuta 5 mseg de ráfaga de CPU Planificación de Threads ( Espacio de usuario )

edu.red

90 Planificación de Threads ( Espacio de kernel ) Quantum por proceso de 50 mseg Cada thread ejecuta 5 mseg de ráfaga de CPU

edu.red

91 Sistemas multiprocesador (Gp:) µP1 (Gp:) µP2 (Gp:) µP3 (Gp:) µP4

Cada µP su cola (Gp:) Peligro de carga desequilibrada

(Gp:) µP1 (Gp:) µP2 (Gp:) µP3 (Gp:) µP4

¡ Ojo ! ? Spin Lock Planificar ? ¿Qué thread? ¿En qué núcleo? Tiempo compartido Threads independientes Cola única (Gp:) No escalable con aumento núcleos

(Gp:) Espera activa si FR ? Spin Lock

(Gp:) ¡Estoy en RC! ? Alarga rodaja

(Gp:) Problemática caches ? Afinidad

edu.red

92 Sistemas multiprocesador Ordenando 128.000 claves "burbuja" en Intel Core 2 Quad Q6600 2,46GHz (Gp:) µP0 (Gp:) 4MB L2 (Gp:) µP1 (Gp:) µP2 (Gp:) 4MB L2 (Gp:) µP3

sched_setaffinity

edu.red

93 Sistemas multiprocesador Espacio compartido Threads cooperantes Apropiarse {µP}n (Gp:) Núcleo ocioso cuando Pi.bloqueado

(Gp:) Sin multiprogramación ? ¡Menos burocracia!

(Gp:) Sin "n" núcleos libres no me ejecuto

(Gp:) Servidor Web con {threads} variable

edu.red

94 Sistemas multiprocesador Planificar por pandillas Threads cooperantes Tiempo/Espacio (Gp:) Espacio compartido

(Gp:) Tiempo compartido

Partes: 1, 2
 Página anterior Volver al principio del trabajoPágina siguiente