S.O - Tema 3 - Gestión de Procesos
description
Transcript of S.O - Tema 3 - Gestión de Procesos
1
SISTEMAS OPERATIVOS
Tema 3: Gestión de Procesos
Índice
• Modelo de ProcesoModelo de Proceso• Llamadas al sistema (creación y
finalización)• Modelo de Thread• Concurrencia
Deadlock• Deadlock• Planificación de CPU (corto plazo)
De programa a proceso
lenguaje de alto nivel -> lenguaje máquina Fase 1
editar
.asm Compilación:traducción de lenguaje de alto nivel a código objeto
.o
.o.c
ficheros fuente
.a
ficheros objeto y librerías
De programa a proceso
lenguaje de alto nivel -> lenguaje máquina Fase 1
editar
.asm.o
.o A.exe
onta
r
Montaje: creación de un fichero ejecutable a partir de varios ficheros objetos y
.c.a
mo
ficheros fuente
ficheros objeto y librerías
ficheros ejecutables
varios ficheros objetos y librerías
2
De programa a proceso
lenguaje de alto nivel -> lenguaje máquina Fase 1
editar
.asm.o
.o A.exe
onta
r
Programa:entidad estática, código almacenado en disco
.c.a
mo
ficheros fuente
ficheros objeto y librerías
ficheros ejecutables
disco
De programa a proceso
lenguaje de alto nivel -> lenguaje máquina ejecución Fase 1 Fase 2
editar
.asm.o
.o A.exe
onta
r SOMemoria CPU
CPA
A.c.a
mo
cargar y ejecutar
A
cargar un fichero en memoria y dar control a la primera instrucción del programa
SOMemoria CPU
CPA
Proceso
Un proceso es un programa en ejecución
A • no existe una relación uno-a-uno entre programa y proceso ya que se puede tener varios procesos de un mismo programa
Programa Proceso
A
main(){...foo(5);
...}
main(){...
foo(5);...}
roceso
pila
registrosCPU
Proceso
SOMemoria CPU
CPA Un proceso es un programa en ejecución
¿Cuántos procesos puede controlar un SO?ATabla de Procesos (TP)
Cada entrada de la TP incluye:- estado del procesador
posición en memoria de
BCP de A
BCP de B- posición en memoria de código, datos, pila del proceso- la información de control requerida por el SO
.....
BCP de nBloque de Control de Proceso (BCP)
3
Proceso
Grado de multiprogramación: nº de procesos activosprocesos activos
Sistema donde todo los procesos residen totalmente en Memoria Principal.
SOMemoria P.
A
CB
cesa
dor 100%
Grado de multiprogramación
Util
izac
ión
delp
roc
0%
Estados de un procesoC
BB
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
en t= 0 • aparecen simultáneamente los procesos A, B y C• el SO le asigna el procesador al proceso Ael SO le asigna el procesador al proceso A• los procesos B y C están listos para ejecutarse cuando el SO les asigne el procesadorde t=0 a t=3• A se está ejecutando (estado EJECUCIÓN)• B y C están esperando que se les asigne CPU (estado LISTO)
Estados de un procesoC
BB
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
en t= 3 • el proceso A ejecuta una petición de un servicio que le supone una espera y deja libre el procesadorp p y j p• el SO le asigna el procesador al proceso B• el proceso C sigue esperando que se le asigne el procesadorde t=3 a t=6• B está en el estado EJECUCIÓN• C está en el estado LISTO.• A está esperando que su petición se realice. Durante esta espera no necesita el procesador (estado BLOQUEADO)
Estados de un proceso
C
B
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Y así seguimos hasta la finalización de todos los procesos
4
Estados de un procesoC
BB
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
l j ióplanificado
entra al sistema finalizaciónlisto ejecución
bloqueado
expira tiempo
Diagrama de estados
planificado
entra al sistemafinalización
finalnuevo
suspendidolisto
listo ejecución
bloqueado procesos activos en Memoria Principal
i
final q
p
swap in
listo
suspendidobloqueado procesos inactivos
en Memoria Secundaria (disco)
swap outswap in
• Información de identificación– PID del proceso, PID del padre
Bloque de Control del Proceso
p p– ID de usuario real (uid real)– ID de grupo real (gid real)– ID de usuario efectivo (uid efectivo)– ID de grupo efectivo (gid efectivo)
• Estado del procesador• Información de control del proceso
– Información de planificación y estadoInformación de planificación y estado– Descripción de los segmentos de memoria del proceso– Recursos asignados (ficheros abiertos, ...)– Comunicación entre procesos.– Punteros para estructurar los procesos en listas o colas.
• Estado del procesador: contenido de los
Información de un proceso
pregistros del modelo de programación.
• Imagen de memoria: contenido de los segmentos de memoria en los que reside el código y los datos del procesoC t id d l bl d t l d l • Contenido del bloque de control del proceso (BCP).
5
M d iRegistros
Información de un proceso
Mapa de memoriadel proceso A
especiales
Tablas del sistema operativoTabla de procesos
BCP Proceso BBCP Proceso A BCP Proceso C
Mapa de memoriadel proceso B
Mapa de memoriadel proceso C
Registrosgenerales • Estado (regt.)
• Identificación• Control
• Estado (regt.)• Identificación• Control
• Estado (regt.)• Identificación• Control
Memoria P.
Tablas SO
CP
SP
PSW
- Tabla de memoria- Tabla de E/S- Tabla de Ficheros
Cambio de contexto
Proceso A Proceso BSO
i t ióinterrupciónE/S
interrupciónreloj
A
A
B
B
Tiemp
A : cambio de modo usuario a supervisor
B : cambio de modo supervisor a usuario
A
B
o
Vamos a realizar un “zoom”
• ¿Qué ocurre en el instante de tiempo 3?¿Có b l SO A lib l d ?
C
• ¿Cómo sabe el SO que A libera el procesador?• ¿Cómo se conmuta de A a B?• .......
C
B
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
C
B
Petición de un servicio al SOSO
Job AB
A0 1 2 3 4 5 6
Job A....while (cond)...endleer_disco(File, buff, num);....
leer disco(F,B,N)SO
_ ( , , )begin
move Cod_op,R1push Fpush Bpush NSYS_CALL
end
C
B
A0 1 2 x x 3 4 5 6
6
SYS_CALL (Trap): • instrucción del repertorio máquina del procesador conocida como llamada al sistema.
Petición de un servicio al SO
• interfaz de programación del SO
Pasos básicos1. salvar CP, PSW2. cambiar a modo supervisor3. salvar estado4. averiguar que servicio se pide5. ejecutar la rutina del SO que realiza el . j q
correspondiente servicio6. según servicio el trabajo actual:
1. debe esperar => escoger otro trabajo2. no espera
7. recuperar trabajo 8. Cambiar a modo usuario9. recuperar CP, PSW
Petición de un servicio al SOLibrería: conjunto de rutinas de uso frecuente• Librerías del sistema:
• hacen llamadas al sistema desde lenguaje de alto nivel
Código usuario Código libreríalenguaje
Código de usuariosistema
Código sistema
g j• hacen más portables los programas
• Librerías de lenguaje •rutinas de uso general (más amigables)•no siempre hacen llamadas al sistema
printf( )
printf(...)
sin()
printf(...)
write()
sin()
write()
Trap n
rutina()
Volvemos del “zoom”
• El instante de tiempo 3 es un ejemplo de lo que stá i nd ntin m nt
C
está ocurriendo continuamente.
• final E/S (intp. HW)• sys_call de B • final E/S (intp. HW)
• sys_call de A (exit)
C
B
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Índice
• Modelo de ProcesoModelo de Proceso• Llamadas al sistema (creación y
finalización)• Modelo de Thread• Concurrencia
Deadlock• Deadlock• Planificación de CPU (corto plazo)
7
Llamadas al sistema: gestión de procesos
int fork()
Retorna:
esta llamada crea un proceso clon (hijo) del proceso que ejecuta la llamada (padre)
• -1 si error• 0 al proceso hijo• Valor mayor que cero en el padre, correspondiente al identificador del proceso hijo (PID).
void exit(int status) finalización de proceso
int getpid()
Retorna:• -1 si error• Valor mayor que cero correspondiente al identificador de proceso (PID).
Obtener el identificador de proceso
Llamadas al sistema: gestión de procesos
¿Qué hace el SO cuando se solicita la creación de un ¿Qué hace el SO cuando se solicita la creación de un proceso?
• Asigna una entrada en la tabla de procesos para el proceso nuevo
• Asigna un ID único de proceso al proceso nuevo• Hace una copia de la imagen del proceso padre (excepto la mem.
comp.)• Incrementa los contadores de los ficheros que son propiedad
del padre• Pone el proceso hijo en el estado Listo para ejecutar
Llamadas al sistema: gestión de procesos
SO
Memoria Principal
Hola
main(){printf(“Hola\n”);fork();printf(“Adios\n”);
}
Hola
?AdiosAdios
main(){printf(“Hola\n”);fork();printf(“Adios\n”);
}
¿qué proceso escribe cada Adiós?
• No se puede hacer suposiciones de velocidades relativas de ejecución de los procesos• ¿cómo discriminamos un código de otro?
Llamadas al sistema: gestión de procesos
SO
i ()
Adiós del hijoAdiós del padre
Hola
main(){int pid;printf(“Hola\n”);pid = fork();if (pid==0) /* hijo */printf(“Adiós del hijo\n”);
else /* padre */printf(“Adiós del padre\n”);
}
HolaAdiós del padreAdiós del hijo
o
HolaAdiós Adiós del hijo d l d
o
Adiós del padre
printf(“Adiós del padre\n”);
main(){int pid;printf(“Hola\n”);pid = fork();if (pid==0) /* hijo */printf(“Adiós del hijo\n”);
else /* padre */printf(“Adiós del padre\n”);
}
Ya sabemos que código ejecuta cada proceso, pero seguimos sin poder saber el orden de ejecución.
del padre
........o
printf(“Adiós del hijo\n”);
8
Llamadas al sistema: ejemplosint flec,fesc;char car;leer_esc(){
Copia el contenido de un fichero (argv[1]) a otro fichero (argv[2])Copia el contenido de un fichero
(argv[1]) a otro fichero (argv[2]){for(;;){if(read(flec,&car,1)!= 1)
return;write(fesc,&car,1);
}}
main(int argc,char *argv[]){
(argv[1]) a otro fichero (argv[2])(argv[1]) a otro fichero (argv[2])
Pero no podemos asegurar que el orden del contenido sea el mismo en ambos
ficheros.
Pero no podemos asegurar que el orden del contenido sea el mismo en ambos
ficheros.
{if (argc != 3)
exit(1);if((flec=open(argv[1],O_RDONLY))== -1) exit(1);if((fesc=creat(argv[2],0666))== -1) exit(1);fork(); /* los dos procesos ejecutan lo mismo */leer_esc();exit(0);
}
Llamadas al sistema: gestión de procesos
int wait(int *status) Espera la finalización de un proceso hijo cualquiera
Retorna:• -1 si error• Valor mayor que cero correspondiente al identificador de proceso hijo (PID).
cualquiera
pid_t waitpid(pid_t pid, int *stat_loc, int options)
Retorna:• -1 si error• Valor mayor que cero correspondiente al identificador de proceso hijo (PID).• 0 el estado del proceso hijo al que se está haciendo referencia no está disponible.
Espera la finalización de un proceso hijo en concreto
Llamadas al sistema: gestión de procesos
SOmain(){int pid,st;{int pid,st;printf(“Hola\n”);pid = fork();if (pid==0) /* hijo */{printf(“Adiós del hijo\n”);}
else /* padre */{wait(&st);printf(“Adiós del padre\n”);}
}
i ()
HolaAdiós del hijoAdiós del padre
main(){int pid,st;printf(“Hola\n”);pid = fork();if (pid==0) /* hijo */{printf(“Adiós del hijo\n”);}
else /* padre */{wait(&st);printf(“Adiós del padre\n”);}
}
Ahora ya sabemos que código ejecuta cada proceso y el orden en que se ejecutarán.
Llamadas al sistema: gestión de procesos
¿cómo conseguir que un proceso ejecute otro programa diferente al que tiene cargado en
memoria?
9
Llamadas al sistema: gestión de procesos
int execlp(char *file, char *arg0,...)Cambiar la imagen ejecutable de un proceso( di d t s il )Retorna:
• -1 si error• si correcto nunca vuelve.
(codigo, datos, pila)
int execl(char *path, char *file, char *arg0,...)
int execle(char *path, char *file, char *arg0,..., char *envp[])
int execv(char *path char *argv[])int execv(char *path, char *argv[])
int execvp(char *file, char *argv[])
int execve(char *file, char *argv[], char *envp[])
Llamadas al sistema: gestión de procesos
SOmain(){int fd; /bin/ls{int fd;printf(“Hola\n”);fd=open(“salida”,O_WRONLY);close(1);dup(fd);close(fd);execlp(“ls”,”ls”,”-l”,NULL);exit(1);
}
0123
TDF
4
TF
1 W 0
...
T. I-nodos
1 fichero
...
2
Llamadas al sistema: gestión de procesos
SOmain(){int fd; /bin/ls{int fd;printf(“Hola\n”);fd=open(“salida”,O_WRONLY);close(1);dup(fd);close(fd);execlp(“ls”,”ls”,”-l”,NULL);exit(1);
}
Cambiar el programa del proceso por el “ls -l”,
codigo del ls
la TDF queda intacta. Entonces, ¿cuál es el resultado final?
El listado proporcionado por “l l”
0123
TDF
4
TF
1 W 0
...
T. I-nodos
1 fichero
...
El listado proporcionado por ls –l se almacena en fichero
fork() wait()pid P
padre padre
pid P
padrepid P
Llamadas al sistema: gestión de procesos
exec() exit()
p
pid Hzombiehijohijo
pid Hhijopid H
pid P pid P pid P pid Ppid Hpid H
texto
datos
pila
datos
Ficheros, tuberías, ...
10
Índice
• Modelo de ProcesoModelo de Proceso• Llamadas al sistema (creación y
finalización)• Modelo de Thread• Concurrencia
Deadlock• Deadlock• Planificación de CPU (corto plazo)
Modelo de Proceso
Proceso versus flujoA cada parte del programa (código) que se puede ejecutar de forma independiente se le asocia un flujo (“thread”, hebra, proceso ligero) proceso ligero).
main(){...
foo(5);...}
Proceso
pila
registrosCPU
main(){...
foo(5);...}
Flujo
pila
registrosCPU
pila
registrosCPU
• un proceso (o proceso pesado) es el dueño de los recursos
• pueden existir múltiples flujos de ejecución en un mismo proceso
Información propia/privada de un flujo:• Contador de Programa (CP)
Flujo (“thread”)Proceso
• Contador de Programa (CP)• Pila• Registros• Estado del flujo (ejecución, listo o
bloqueado)
Todos los flujos de un mismo proceso comparten:
• Espacio de memoria
Código
Datos
Recursos (ficheros, ...)
Entorno del procesop• Variables globales• Archivos abiertos• Temporizadores• Señales y semáforos
Flujo 1Registros
Pila
Flujo nRegistros
Pila
....
11
Creación Threads vs. Proceso
Nota: Tiempos reflejan la creación de 50,000 procesos/thread, fuemedido con la utilidad “time”, las unidades en segundos.
Código: fork() Vs Pthread_create ()
Estados del proceso ligero
ProcesoActivo
Bloqueado por acceso a discoBloqueado por comunicación
Procesos ligeros
Ejemplo utilizacion de Threads
12
Procesos ligeros: diseño de servidores
Dispatcher thread Worker thread
Modelos comunes:
Modelos de programas con threads
Modelos comunes: – Master/worker: static worker pool Vs dynamic worker pool. – Pipeline: tarea rota en series de
suboperaciones cada una de las cuales esmanejada en serie, pero concurrentemente porthreads diferentes threads diferentes.
– Peer: similar al manager/worker model, perodespués de crear otros threads, el participa en el cómputo.
Otros modelos: OpenMP Hilos nivel usuario/nucleo
Bibliotecade hilos
Bibliotecade hilos
Espaciode usuario
Espaciode usuario
Espaciode
usuario
Espaciode núcleo
Espaciode núcleo
Espaciode núcleo
(a) Nivel de usuario puro (b) Nivel de núcleo puro (c) Combinado
Hilo a nivel de usuario
Hilo a nivel de núcleo Proceso
13
Servicios POSIX para la gestión de procesos ligeros
• int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*func)(void *), void *arg)
– Crea un proceso ligero que ejecuta "func" con argumento "arg" y atributos "attr".– Los atributos permiten especificar: tamaño de la pila, prioridad, política de
planificación, etc.– Existen diversas llamadas para modificar los atributos.
• int pthread_join(pthread_t thid, void **value)– Suspende la ejecución de un proceso ligero hasta que termina el proceso ligero
con identificador "thid". – Devuelve el estado de terminación del proceso ligero.
i h d i ( id * l )• int pthread_exit(void *value)– Permite a un proceso ligero finalizar su ejecución, indicando el estado de
terminación del mismo.• pthread_t pthread_self(void)
– Devuelve el identificador del thread que ejecuta la llamada.
Servicios POSIX para la gestión de procesos ligeros II
• int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)– Establece el estado de terminación de un proceso ligero.– Si "detachstate" = PTHREAD_CREATE_DETACHED el proceso
ligero liberara sus recursos cuando finalice su ejecución.– Si "detachstate" = PTHREAD_CREATE_JOINABLE no se liberarn
los recursos, es necesario utilizar pthread_join().
Atrib: Conexión CPU Vs Memoria
• Recursos compartidos (buses, cache L2, L3, etc.). Adaptar los gestores (afinidad, power, etc).
Futuro previsto en 5 años
• 128 cores por socket
• 32 sockets por node
• 128 nodes por sistema
• Sistema = 128*32*128524 288 Co es!
52
= 524,288 Cores!
• 4 threads por core• 2M threads a manejar
14
#include <pthread.h>void print_fun( void *message ) {
printf("%s \n", message);}
Ejemplo 1
}
main() {pthread_t thread1, thread2;char *message1 = "Hello";char *message2 = "World";
pthread_create( &thread1,NULL,( id*)& i t f
Compile using gcc –lpthread
Nota: Condición de carrera en la sentencia print(void*)&print_fun,
(void*) message1);pthread_create(&thread2,
NULL,(void*)&print_fun,(void*) message2);
return(0);}
Ejemplo 2#include <stdio.h>#include <pthread.h>#define MAX_THREADS 10void func(void) {void func(void) {
printf("Thread %d \n", pthread_self());pthread_exit(0);
}main() {
int j;pthread_attr_t attr;pthread_t thid[MAX_THREADS];pthread_attr_init(&attr);for(j = 0; j < MAX_THREADS; j ++)
pthread_create(&thid[j], &attr, func, NULL);for(j = 0; j < MAX_THREADS; j ++)
pthread_join(thid[j], NULL);}
Índice
• Modelo de ProcesoModelo de Proceso• Llamadas al sistema (creación y
finalización)• Modelo de Thread• Concurrencia
Deadlock• Deadlock• Planificación de CPU (corto plazo)
¿Qué es concurrencia?
• “Interleaving”: intercalar en el tiempo la ejecución de más de un proceso/flujo (multipro ramación)de más de un proceso/flujo (multiprogramación)
C
B
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
• La ejecución de los procesos/flujos NO se solapa en el tiempo (tramos de color rojo).
• Sin embargo, la “vida” de los procesos/flujos SI se solapa en el tiempo (líneas azules)
15
¿Qué es concurrencia?• Paralelismo: existe simultaneidad en la ejecución
ya que disponemos de más de un procesador.ya que disponemos de más de un procesador.
C
B
A0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Procesador 2
Procesador 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
• La ejecución de procesos/flujos en procesadores/cores diferentes SI se solapa en el tiempo.
¿Qué es concurrencia?• Relación entre procesos :
• Desconocimiento total: los procesos compiten p ppor los recursos del sistema. Los resultados de un proceso/flujo son independientes de los de otro. Problemas: Exclusión Mutua, “Deadlock”, “Starvation”
• Indirecta: cooperación por compartir. Los resultados de algún proceso/flujo depende de g p j pinformación capturada por otro. Problemas: EM, “Deadlock”, “Starvation”, Coherencia de los datos.
• Directa: cooperación por comunicación (mensajes). Problemas: “Deadlock”, “Starvation”.
¿Qué es concurrencia?
IMPORTANTE:
• Recordar que NO existe ninguna garantía en el orden de ejecución de los procesos/flujos.
• Para conseguir un orden explícito se deberá incluir l ú ét d d i i ió l algún método de sincronización que nos lo asegure.
¿Qué es concurrencia?• Instrucciones simples de lenguajes de alto nivel (C,
Java etc ) normalmente se traducen en más de Java, etc...) normalmente se traducen en más de una instrucción de lenguaje máquina.
Ejemplo:.....cont++;.....
mov al,contadd al, 1mov cont, al
• Tras la finalización de cualquiera de las tres instrucciones anteriores se puede atender una interrupción o producirse un cambio de contexto.
• La mayoría de las instrucciones de alto nivel NO son atómicas.
16
Operación AtómicaUna operación atómica es aquella que no puede
interrumpirse durante su ejecución.
• Las instrucciones máquina son atómicas.mov al, cont
Esta instrucción no puede romperse por causa de alguna interrupción.
L i t i d lt i l NO tó i• Las instrucciones de alto nivel NO son atómicascont++;
Esta instrucción es realmente 3instrucciones máquina.Se puede producir una interrupción durante la ejecución de la instrucción.
Problema !• Supongamos 2 flujos (procesos) accediendo a una variable compartida.
int cont=2;i ()
void flujo0(){
void flujo 1(){main()
{crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
{...cont++;...
}
{...cont--;...
}
• Recordar que cont++ y cont–- son en realidad 3 instrucciones máquina.• Un posible “interleaving” de los flujos flujo0 y flujo1 es:Un posible interleaving de los flujos flujo0 y flujo1 es:
flujo1 mov al,contflujo2 mov al,contflujo1 add al,1flujo2 sub al,1flujo1 mov cont, alflujo2 mov cont, al
El resultado es que cont vale 2
Según el “interleaving” cont podría valer 1, 2 o 3
Condición de carrera(“race condition”)
• El ejemplo anterior es un caso donde se produce la condición de carrera:de carrera:
dos flujos compiten (“carrera”) para poner un valor en una posición de la memoria
no existe ninguna manera de saber quien “ganará”
• “Bug” muy problemático.es complicado de reproducir (ejecución no determinista)
l d d l i i d i d ya que el orden de las instrucciones puede variar de una ejecución a otra.
sin una salida consistente, es muy complejo determinar los errores.
Sección Crítica• Si existen varios flujos/procesos que acceden a datos
compartidos los cuales son modificables, entonces el acceso a di h d t d fl j / d b t l ddichos datos por cada flujo/proceso debe ser controlado.
• La parte de código que debe ser controlada en cada flujo/proceso se conoce como su SECCIÓN CRÍTICA.
int cont=2;main(){
void flujo0(){
...
void flujo1(){
...{crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
cont++;...
}
cont--;...
}
SECCIÓN CRITICA
17
Sección Críticavoid flujo0(){
...entrarSeccionCritica();
void flujo1(){
...entrarSeccionCritica();
cont++;salirSeccionCritica();...
}
cont--;salirSeccionCritica();...
}
• entrarSeccionCritica() y salirSeccionCritica() son dos requerimientos para proteger de forma correcta la SC. Se puede ver como un protocolo de acceso y salida de la SCcomo un protocolo de acceso y salida de la SC.
• Este par de funciones deben cumplir:• Exclusión mutua• Progreso• Espera limitada
• No se pude hacer ninguna hipótesis sobre el nº de procesadores, ni la velocidad de ejecución.
Sección CríticaProtección “SOware”
El SO nos proporciona las herramientas pero es el programador el que ha de usarlas adecuadamente.
• Semáforo: es una estructura de datos del SO que tiene asociada un contador y una cola de procesos bloqueados.
• Sirve para proteger el acceso a recursos.
• El contador indica la cantidad de accesos simultáneos que permitimos al recurso que protege el semáforo.
• Solo es accesible mediante dos primitivas: wait() y signal().
Sección CríticaProtección “SOware”: semáforos
void wait(semaforo s){
void signal(semaforo s){
while(s <= 0 );s--;
}
{s++;
}
• Para que el semáforo funcione correctamente, las primitivas wait() y signal() tienen que ser atómicas.
• Darse cuenta que estas primitivas no devuelven ningún valor Darse cuenta que estas primitivas no devuelven ningún valor. Simplemente retornando de ellas o bien se ha obtenido o liberado acceso al recurso que protege el semáforo.
Sección CríticaProtección “SOware”: semáforos
Veamos como solucionamos el problema del acceso a la SC utilizando semáforos.
int cont=2;compartido
Queremos asegura EM l semaforo s;
main(){
sem_init(s,??);crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
compartido
¿cuántos accesos simultáneos queremos permitir sobre cont?
EM, entonces solo 1 acceso simultáneo.
1
entrarSeccionCritica();SeccionCritica();salirSeccionCritica();
void flujo0(){
???cont++;???
}
void flujo1(){
???cont--;???
}
18
Sección CríticaProtección “SOware”: semáforos
Veamos como solucionamos el problema del acceso a la SC utilizando semáforos.
¿Cómo asegurar que el int cont=2;
¿Cómo asegurar que la ¿Cómo asegurar que el flujo0 entra en su SC impidiendo que el flujo1 pueda, a partir de ese momento, entrar en su SC?
semaforo s;main(){
sem_init(s,1);crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
¿Cómo asegurar que la ejecución del flujo1 se “detiene” si el flujo0 se está ejecutando en su SC?
entrarSeccionCritica();SeccionCritica();salirSeccionCritica();
void flujo0(){
???cont++;???
}
void flujo1(){
???cont--;???
}
Sección CríticaProtección “SOware”: semáforos
Veamos como solucionamos el problema del acceso a la SC utilizando semáforos.
int cont=2;¿Cómo asegurar que la ¿Cómo asegurar que el semaforo s;
main(){
sem_init(s,1);crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
¿Cómo asegurar que la ejecución del flujo1 se “detiene” si el flujo0 se está ejecutando en su SC?
¿Cómo asegurar que el flujo0 entra en su SC impidiendo que el flujo1 pueda, a partir de ese momento, entrar en su SC?
entrarSeccionCritica();SeccionCritica();salirSeccionCritica();
void flujo0(){
wait(s);cont++;???
}
void flujo1(){wait(s);cont--;???
}
Sección CríticaProtección “SOware”: semáforos
Veamos como solucionamos el problema del acceso a la SC utilizando semáforos.
int cont=2;semaforo s;main(){
sem_init(s,1);crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
¿Cómo asegurar que el flujo0 al salir de su SC libera el acceso al recurso cont ?
entrarSeccionCritica();SeccionCritica();salirSeccionCritica();
void flujo0(){
wait(s);cont++;???
}
void flujo1(){wait(s);cont--;???
}
Sección CríticaProtección “SOware”: semáforos
Veamos como solucionamos el problema del acceso a la SC utilizando semáforos.
int cont=2;semaforo s;main(){
sem_init(s,1);crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
¿Cómo asegurar que el flujo0 al salir de su SC libera el acceso al recurso cont ?
entrarSeccionCritica();SeccionCritica();salirSeccionCritica();
void flujo0(){
wait(s);cont++;signal(s);
}
void flujo1(){wait(s);cont--;
signal(s);}
19
Sección CríticaProtección “SOware”: semáforos
Con un semáforo inicializado a 1 podemos controlar el acceso a la SC de N flujos asegurando la Exclusión Mutua.
void flujo0(){
wait(s);SeccionCritica();signal(s);
}
int cont=2;semaforo s;main(){
int i;i it( 1)
..............
void flujoN(){wait(s);SeccionCritica();signal(s);
}
sem_init(s,1);for (i=0;i<N;i++)
crear_flujo(flujoi);esperaFinalFlujos();
}
Sección CríticaProtección “SOware”: semáforos
Problema de los semáforos
void wait(semaforo s) Si el semáforo no está void wait(semaforo s){
while(s <= 0 );s--;
}
Si el semáforo no está disponible, el flujo se quedará en el bucle while gastando ciclos de CPU sin hacer nada productivo, sin permitir que otro flujo pueda sacar provecho de dichos ciclos.
Esp A ti ¿ Cuál puede ser la
Solución ? Espera Activa o
Espera Ocupada
Solución ?
Bloquear el Fluj
Sección CríticaProtección “SOware”: semáforos
void wait(semaforo s){
void signal(semaforo s){{
s--;if (s < 0) bloquearme();
}
{s++; if (s<=0){
w = extraerProcesoLista();desbloquear(w);}
}
• La lista de procesos bloqueados se implementa como lista • La lista de procesos bloqueados se implementa como lista encadenada usando el campo puntero de los BCP.
• Estas primitivas han de ser atómicas.
Sección Críticawait() y signal() como secciones críticas
lock = 0;int i, cont=2;semaforo s;
void wait(semaforo s){
while(test&set(&lock));semaforo s;main(){
sem_init(s,1);for (i=0;i<N;i++)
crear_flujo(flujoi);esperaFinalFlujos();
}
s--;if (s < 0) {
lock=0;bloquearme();
}lock = 0;
}
void flujoi(){
wait(s);SeccionCritica();signal(s);
}
Como podemos ver aun existe espera activa. Sin embargo esta espera no la podemos eliminar (es mínima y necesaria)
20
Sección Críticawait() y signal() como secciones críticas
lock = 0;int i, cont=2;semaforo s;
void wait(semaforo s){
while(test&set(&lock));semaforo s;main(){
sem_init(s,1);for (i=0;i<N;i++)
crear_flujo(flujoi);esperaFinalFlujos();
}
s--;if (s < 0) {
lock=0;bloquearme();
}lock = 0;
}
void signal(semaforo s){
void flujoi(){
wait(s);SeccionCritica();signal(s);
}
void signal(semaforo s){while(test&set(&lock));s++;if (s <=0) {desbloquear un proceso;
}lock = 0;
}
Semáforos ++• En función del valor inicial del contador asociado al semáforo,
utilizaremos a este para diferentes funciones:• sem init (s 1): ya hemos visto su utilidad para conseguir sem_init (s, 1): ya hemos visto su utilidad para conseguir
que N procesos accedan con Exclusión Mútua a sus respectivas SC.
• sem_init (s, 0): sincronización; marcar orden de precedencia
• sem_init (s, N): sincronización; restricción de recursos (semáforo genérico)
• Ejemplos de sincronización:• Productor/consumidor• Comida de los filósofos• Lectores/escritores
Marcar orden de precedenciasmain(){
crear flujo (flujo0);
void flujo0(){
acción 01;
void flujo1(){
acción 11;c ea _ ujo ( ujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
acc ó 0 ;....acción 02;
}
acc ó ;....acción 12;
}
Supongamos que se debe cumplir el siguiente orden en la ejecución de las diferentes acciones (orden de precedencia):
- acción 01 y acción 11 pueden realizarse concurrentemente,- acción 02 debe realizarse siempre después de haberse realizadola acción 12 (y evidentemente después de la acción 01).
¿Cómo conseguirlo?
Marcar orden de precedenciasmain(){
Sem_init (s,..);Sem_init (s, 0);
Flujoprincipal
crear_flujo (flujo0);crear_flujo (flujo1);esperaFinalFlujos();
}
void flujo0(){
void flujo 1(){
accion01
accion02
accion11
accion12
{acción 01;......acción 02;
}
acción 11;......acción 12;
}
Flujoprincipal
Grafo de precedencias
signal(s);wait(s);
21
Productor/ConsumidorBuffer circular de tamaño limitado (N posiciones)
inoutint buffer[N],in,out;main(){
crearFlujo(consumidor);crearFlujo(productor);esperarFinalFlujos();
}
int buffer[N],
void consumidor() void productor()void consumidor(){
acceder_buffer_sacar(ele); consumir_elemento();
}
Debe existir como mínimo 1 elemento en el buffer, sino esperarse
void productor(){
ele = producir_elemento();acceder_buffer_introducir(ele);
}
Debe existir como mínimo 1 espacio vacío en el buffer, sino esperarse
Productor/Consumidor
int buffer[N],in,out;semaforos hay_ele, hay_esp, mutex;main(){ sem init(hay ele,0);
void consumidor(){
void productor(){
{ sem_init(hay_ele,0);sem_init(hay_esp,N);sem_init(mutex,1);.....
}
wait(hay_ele);wait(mutex);acceder_buffer_sacar(ele); signal(mutex);signal(hay_esp);consumir_elemento();
}
ele = producir_elemento();wait(hay_esp);wait(mutex);acceder_buffer_introducir(ele);signal(mutex);signal(hay_ele);
}
Comida de los Filósofosmain(){
for (i=0;i<5;i++)l j (filó f (i))crearFlujo(filósofo(i));
esperarFinalFlujos();}
d no puede
void filósofo(i){
while(true) {PENSAR();
COME
no puede comer
no puede comer
PENSAR();coger_tenedor_der();coger_tenedor_izq();COMER();}
}
Comida de los Filósofos
semaforo tenedor[5];
void filósofo(i){
while(true) {semaforo tenedor[5]; main(){
for (i=0;i<5;i++)sem_init(tenedor[i],1);
for (i=0;i<5;i++)crearFlujo(filósofo(i));
esperarFinalFlujos();}
PENSAR();wait(tenedor[i]);coger_tenedor_der();wait(tenedor[(i+1)%5]);coger_tenedor_izq();COMER();signal(tenedor[i]);signal(tenedor[(i+1)%5]);} g ( [( ) ]);}
}
Problema: Los filósofos pueden morir de inanición debido a un interbloqueo si cada filósofo puede coger uno y solo un tenedor de la mesa
22
Comida de los Filósofosvoid filósofo(i){
while(true) {PENSAR();
coger_tenedor(i){wait(mutex);state(i):= hungry;
dejar_tenedor(i){wait(mutex);state(i):= thinking;
PENSAR();coger_tenedor(i);COMER();dejar_tenedor(i);}
}
test (i);signal(mutex);wait(s(i));
}
test (left);test (right);signal(mutex);
}
test (i){
if (state(i) == hungry && state(left) != eating && state(right) != eating
signal(s(i));
}
Lectores/Escritoreslector 1
lector 2lector n
escritor 1escritor iescritor i
lector i
Escritor accede a datos:• solo un escritor simultáneamente• otros escritores se esperan• lectores se esperan
Lector accede a datos:• pueden accede simultáneamente
n lectores• los escritores se esperan
Lectores/Escritores(prioridad lectores)
Mientras existan lectores que quieran acceder a los datos, los escritores se esperaran, independientemente del orden en que se solicite el acceso a los datos
int cont lect;int cont_lect;semaforos esc, mutex;main(){ sem_init(esc,1);
sem_init(mutex,1);cont_lect = 0;.....
}
void lector(){
wait(mutex);cont_lect = cont_lect + 1;if (cont_lect == 1 ) wait(esc);signal(mutex);leer();
void escritor(){
wait(esc);escribir();signal(esc);
}
wait(mutex);cont_lect = cont_lect – 1;if (cont_lect == 0) signal(esc);signal(mutex);
}
// pthread_mutex_t mymutex =PTHREAD_MUTEX_INITIALIZER;
Threads Mutexes
#define P_M_L(x) pthread_mutex_lock(x) #define P_M_U(x) pthread_mutex_unlock(x)
pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t bar_mutex = PTHREAD_MUTEX_INITIALIZER; int foo = 0, bar = 0;
void foo bar inc()void foo_bar_inc() { P_M_L(&foo_mutex);P_M_L(&bar_mutex); bar = foo++;P_M_U(&bar_mutex); P_M_U(&foo_mutex); }
23
• Variables de sincronización asociadas a un mutex • Conveniente ejecutarlas entre lock y unlock • Dos operaciones atómicas:
Threads: variables tipo condición
• Dos operaciones atómicas: – wait Bloquea al proceso ligero que la ejecuta y le expulsa del mutex – signal Desbloquea a uno o varios procesos suspendidos en la variable condicional. El
proceso que se despierta compite de nuevo por el mutex Proceso ligero B
Proceso ligero A
locklock
waitunlock mutex
Adquiere el mutex
Adquiere el mutex
Se compite por el mutex
unlock
Proceso ligero bloqueado esperando signal
Proceso ligero bloqueado esperando unlock
signal
Threads: variables tipo condición
Proceso ligero Alock(mutex); /* acceso al recurso */
comprobar las estructuras de datos;while (recurso ocupado)
wait(condition, mutex);marcar el recurso como ocupado;
unlock(mutex);
Proceso ligero B
lock(mutex); marcar el recurso como libre;signal(condition, mutex);
unlock(mutex);
unlock(mutex);
Importante utilizar while
Índice
• Modelo de ProcesoModelo de Proceso• Llamadas al sistema (creación y
finalización)• Modelo de Thread• Concurrencia
Deadlock• Deadlock• Planificación de CPU (corto plazo)
Interbloqueos• Bloqueo permanente de un conjunto de procesos
que compiten por los recursos del sistema o se comunican entre sí.
• Ejemplo: Si P y Q con semáforos con valor inicial 1
P1 P2wait(P) wait(Q)wait(P) wait(Q)wait(Q) wait(P)... ...
signal(P) signal(Q)signal(Q) signal(P)
24
Ejemplo de interbloqueo
P
BA
Q
Interbloqueos II• Ejemplo: Si C1 y C2 son dos colas de
mensajes: P1 P2
receive(P2, M) receive(P1, N)... ...
send(P2, M) send(P1, N)
• Condiciones del interbloqueo: – Exclusión mutua – Retención y espera – No apropiación – Espera circular
Índice
• Modelo de ProcesoModelo de Proceso• Llamadas al sistema (creación y
finalización)• Modelo de Thread• Concurrencia
Deadlock• Deadlock• Planificación de CPU (corto plazo)
CPU Scheduling
• Scheduling the processor among all ready g p g yprocesses
• The goal is to achieve: – High processor utilization– High throughput
• number of processes completed per of unit time
– Low response time• time elapsed from the submission of a request until
the first response is produced
25
Classification of Scheduling Activity
• Long-term: which process to admit?• Medium-term: which process to swap in or out?• Short-term: which ready process to execute next?
Queuing Diagram for Scheduling
Planificador a Corto Plazo
Consiste en asignar procesador a los procesos listos para ser ejecutados, de manera tal que se cumplan los objetivos del sistema.
Definición de las Políticas de Planificación
Función de Selección: ¿Qué proceso se ejecutará?Función de Selección: ¿Qué proceso se ejecutará?– Prioridades– Necesidades de recursos– Características de los procesos
Modo de selección: ¿Cuándo?¿– No apropiativo– Apropiativo
26
Ejemplo para el Análisis de las Políticas de Planificación a Corto
PlazoProceso Llegada Ts
P1 0 3
P2 2 6P3 4 4P4 6 5P5 8 2
› Tiempo de Espera (Tw)
› Tiempo de Retorno. (Tq)
› Tiempo de Retorno Normalizado (Tqn) Tqn = Tq/Ts
› Tiempo de Respuesta (Tr)
First Come First Served (FCFS)
F ió d l ió [T ] l• Función de selección: max [Tespera], los procesos se atienden por orden de llegada.
• Modo de decisión: No apropiativo
First Come First ServedProceso Llegada Ts
P1 0 3
Tw(P1) = 0
Tw(P2) = 3-2 = 1P1 P2 P5P3 P4
P2 2 6P3 4 4P4 6 5P5 8 2
P5
Tw(P3) = 9-4 = 5
Tw(P4) = 13-6 = 7
Tw(P5) = 18-8 = 10
Tw = 23/5 = 4,6
P4P3P2P1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
First Come First ServedProceso Llegada Ts
P1 0 3
P2 2 6
Tq(P1) = 3
Tq(P2) = 9-2 = 7
Tq(P3) = 13 4 = 9
Tqn(P1) =3/3 = 1
Tqn(P2) =7/6 = 1,16
Tqn(P3) =9/4 = 2 25 P2 2 6P3 4 4P4 6 5P5 8 2
P5
Tq(P3) = 13-4 = 9
Tq(P4) = 18-6 = 12
Tq(P5) = 20-8 = 12
Tq = 43/5 = 8,6
Tqn(P3) =9/4 = 2,25
Tqn(P4) =12/5 = 2,4
Tqn(P5) =12/2 = 6
Tqn = 2,56
P4P3P2P1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
27
First Come First Served (FCFS)• Características:
– Sencillo– Tiempo de espera promedio elevado– Penaliza a los procesos cortos y a los que tienen
mucha E/SInanición: no– Inanición: no
Round Robin• Cada proceso se ejecuta durante una fracción
d ti t d l d (Q t )de tiempo antes de ser expulsado (Quantum)• Modo de decisión: Apropiativo (basado en el
quantum)
Round RobinP ro ceso L leg ad a T s
P 1 0 3 P1 P2 P3 P4 P5P2 P4
P5
P 2 2 6P 3 4 4P 4 6 5P 5 8 2 Quantum = 4
SobrecargaP4P3P2P1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
P2 P3 P4 P5P1
g
Round Robin
• Características:– Rendimiento en función del quantum
– q pequeño => número elevado de cambios de contexto– q pequeño => tiempo de retorno elevado– q grande => utilización de la CPU elevada, pero tiempo
de respuesta elevado también– q pequeño => productividad baja– q ideal => 80% de las ráfagas de CPU deben ser mas q g
pequeñas que el quantum– q mucho más grande que el cambio de contexto
– Quantum: entre 100 y 200 milisegundos. – El quantum es sintonizable!.
28
Round Robin• Características:
d l li i f l b j– Reduce la penalización que sufren los trabajos cortos con FCFS
– Inanición: No, pero tiempo de espera elevado– Buen tiempo de respuesta– Penaliza a los procesos con E/S.
Prioridades
• Función de selección: max [prioridad]• Función de selección: max [prioridad]• Modo de decisión:
– Apropiativo
PrioridadesP ro ceso L leg ad a T s P rio
P 1 0 3 1- 1P 2 2 6 2P 3 4 4 3P 4 6 5 3P 5 8 2 4+
P5
42
P4P3P2P1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
P2 P3 P4 P5P1
Prioridades
• Características:• Características:– Inanición: Posible– Penaliza a los procesos de baja prioridad– Solución: Envejecimiento
29
Colas Multinivel
Alta Prioridad Procesos del Sistema
Procesos Interactivos
P B t hBaja Prioridad Procesos Batch
Colas con Retroalimentación
• Preferencia a los trabajos más cortos• Preferencia a los trabajos más cortos.• Se penaliza a los trabajos que han estado
ejecutandose durante más tiempo.• Se hace una planificación apropiativa y se
emplea un mecanismo dinámico de prioridades.p p
Colas con Retroalimentación
EntradaCPU
LiberarCola 0
CPULiberarCola 1
CPULiberarCola N
Colas con Retroalimentación. Parámetros
• Número de colas• Número de colas.• Algoritmo de planificaciones para cada cola.• Método utilizado para determinar cuando.
promocionar un proceso a una cola de mayor prioridad.p
• Método utilizado para determinar cuando mover un proceso a una cola de menor prioridad.
• Método utilizado para determinar a que cola será inicialmente asignado un proceso.
30
Thread Scheduling• Distinction between user-level and kernel-
level threads• Many-to-one and many-to-many models,
thread library schedules user-level threads to run on LWP– Known as process-contention scope (PCS)
since scheduling competition is within thesince scheduling competition is within the process
• Kernel thread scheduled onto available CPU is system-contention scope (SCS) –competition among all threads in system
Pthread Scheduling• API allows specifying either PCS or SCS
d i th d tiduring thread creation– PTHREAD SCOPE PROCESS schedules
threads using PCS scheduling– PTHREAD SCOPE SYSTEM schedules
threads using SCS scheduling.
Pthread Scheduling API#include <pthread.h>#include <stdio.h>#define NUM THREADS 5#define NUM THREADS 5int main(int argc, char *argv[]){
int i;pthread t tid[NUM THREADS];pthread attr t attr;/* get the default attributes */pthread attr init(&attr);/* set the scheduling algorithm to PROCESS or SYSTEM */pthread attr setscope(&attr, PTHREAD SCOPE SYSTEM);/* set the scheduling policy - FIFO, RT, or OTHER */
(& SC O )pthread attr setschedpolicy(&attr, SCHED OTHER);/* create the threads */for (i = 0; i < NUM THREADS; i++)
pthread create(&tid[i],&attr,runner,NULL);
Pthread Scheduling API
/* now join on each thread */for (i = 0; i < NUM THREADS; i++)
pthread join(tid[i], NULL);}/* Each thread will begin control in this function */void *runner(void *param){
printf("I am a thread\n");pthread exit(0);
}
31
Multiple-Processor Scheduling
• CPU scheduling more complex when multiple CPUs are available
• Homogeneous processors within a multiprocessor• Asymmetric multiprocessing – only one processor
accesses the system data structures, alleviating the need for data sharing
• Symmetric multiprocessing (SMP) – each processor is self-scheduling, all processes in common ready queue, or each has its own private queue of ready processes
• Processor affinity – process has affinity for processor on which it is currently running– soft affinity– hard affinity
NUMA and CPU Scheduling
Multicore Processors
• Recent trend to place multiple processor• Recent trend to place multiple processor cores on same physical chip
• Faster and consume less power• Multiple threads per core also growing
– Takes advantage of memory stall to makeTakes advantage of memory stall to make progress on another thread while memory retrieve happens
Multithreaded Multicore System
32
Ejemplo: Planificación en UNIX
• Beneficia a los procesos interactivos• Beneficia a los procesos interactivos.• Retroalimentación multinivel usando Round
Robin en cada una de las colas de prioridad.• Prioridad calculada cada segundo en función de la
clase de proceso y su historial de ejecución.p y j• Al usar más CPU disminuye la prioridad.• Envejecimiento para evitar inanición.
Ejemplo: Planificación en Win NT
• Planificación cíclica con prioridades y expulsión.• 32 niveles de prioridades:
– 16 niveles con prioridades de tiempo real (16-31)– 16 niveles con prioridades variables (0-15)
• Todos los procesos en el mismo nivel: Round Robin (quantum por proceso).
• Prioridad Variable:Prioridad Variable:– Decrementa la prioridad si acaba su quantum.– Incrementa la prioridad si se bloquea (E/S).
• Buen tiempo de respuesta de los threads interactivos.