View
111
Download
2
Category
Preview:
Citation preview
MultiprogramaciónProcesos
Cecilia Hernández
2007-1
Terminología
MultiprogramaciónEjecutar multiples programas al
mismo tiempoRequiere multiplexar la CPU
• Tranferencia de control entre programas en ejecución mediante
• Cambio de contexto
Proceso : Programa en ejecucióngcc firefox word firefox
tiempo
Procesos
Abstracción de SO de programa en ejecución
Asociado a un espacio de direccionamiento
Adelanto, múltiples hebras de control comparten mismo espacio de direccionamiento código
(text segment)
Datos estáticos(data segment)
heap(mem dinámica)
stack(mem dinámica)
Espacio de direccionamiento
SP
PC
Multiplexando CPU en el tiempo
SO mantiene estructuras de datos para identificar procesos PCB (Process Control Block)
• SO matiene un PCB por cada proceso que está ejecutando en el sistema (para cuando no están usando CPU)
SO ejecuta cambio de contexto para quitar y dar CPU a par de procesos Salva estado de proceso que sale de CPU
en PCB de proceso Recupera estado de PCB de proceso que
entra a CPU para luego ejecutarlo
PCB
Estructura de datos con muchos campos Identificador de proceso (PID) Estado de ejecución (Listo, en ejecución, bloqueado) PC, SP, registros Información de administración de memoria Usuario al que pertenece Prioridad en ejecución Información para administración
En linux Definida en task_struct (include/linux/sched.h)
• Posee muchos más campos de los mencionados arriba
Estados de los procesos
En ejecución
listo
Bloqueado
Interrupción
Sale de CPU
Se despacha a CPU
interrupción(completa E/S)
Espera E/S
Colas de procesos
SO mantiene diversas colas para representar los procesos en el sistema Cola de procesos listos: Procesos que están
en condiciones de ejecutarse esperando por entrega de CPU
Cola de procesos bloqueados: Procesos que esperan por alguna condición para estar listos para ejecutarse
Cuando un proceso cambia de estado, su PCB se desenlaza de una cola para enlazarse a otra
Colas de Procesos
Hay muchas colas de espera, una por cada tipo de espera (dispositivo E/S específico, red, etc)
Ptr headPtr tail
firefox pcb emacs pcb gcc pcb
cat pcb firefox pcbPtr headPtr tail
Encabezado cola espera
Encabezado cola listos
Cambio de contexto Proceso mediante el cual se cambia de un proceso en
ejecución a otro Proceso A entra en kernel
Producto de llamada a sistema, interrupción o excepción El Planificador del SO se ejecuta
Es tiempo de cambio de contexto? Si, sacar de cola de listos siguiente proceso a ejecutar.
Proceso B Rutina en assembly intercambia información de estado del
HW Salva el estado de proceso A en su PCB Restaura estado de proceso B de su PCB Salvar y recuperar estado, incluye CPU y adm de
memoria virtual y resets de caches Ejecuta proceso B OS retorna a modo usuario
Cambio de contexto en linux
Para cambio relacionado con la memoria Include/asm/mmu_context.h
Para cambio de recursos de CPU include/asm/system.h
• Aqui se define una macro llamada switch_to(prev,next,last)
• Para mayor información de los detalles de esta macro revisar
Bovet Daniel P., Sesati Marco, “Understanding the Linux Kernel” (2nd Edition). O'Reilly Media, Inc. 2002
Procesos en Unix
Como crear aplicaciones usando procesos? Usando Llamadas a sistema
Fork : crea un nuevo proceso Exec : ejecuta un programa en proceso
(varios formatos disponibles) Kill : envia señales a procesos
• Pueden ser de término o no
Wait : espera por proceso hasta que termina• Varios formatos
Creación de procesos en Unix
Usando llamada a sistema fork() Básicamente, copia proceso padre
Proceso hijo obtiene un espacio de direccionamiento igual al del padre, pero es independiente
Proceso hijo hereda todos los archivos abiertos del padre
Fork se comporta diferente a cualquier llamado Retorna dos veces
• Retorna el pid del hijo al padre• Retorna 0 al hijo
Ejemplo fork
#include <unistd.h>
int value = 5;
int main () { pid_t pid ;
value = 7;
pid = fork(); if (pid == 0) { // hijo value += 15; } else { // Padre wait (NULL); // espera a que hijo termine printf("PADRE: value = %d\n",value ); }}
Qué valor es impreso en pantalla?
Fork versus exec
Fork() Sólo permite crear nuevo proceso copiando al padre Como hacer que el hijo ejecute algo diferente
• Usando exec()• Ejemplo
• Int exec( char *prog, char **argv) Exec()
Detiene proceso actual Carga programa ‘prog’ en espacio de direccionamiento Inicializa nuevo contexto, args para ‘prog’ Pone PCB proceso en cola de listos NO CREA nuevo proceso, solo cambia lo que esta en
espacio de direcciomiento
Variaciones de exec()
int ret;ret = execl ("/bin/ls", "ls", "-1", (char *)0);
char *env[] = { "HOME=/usr/home", "LOGNAME=home", (char *)0 };ret = execle ("/bin/ls", "ls", "-l", (char *)0, env);
ret = execlp ("ls", "ls", "-l", (char *)0) char *cmd[] = { "ls", "-l", (char *)0 };ret = execv ("/bin/ls", cmd);
char *cmd[] = { "ls", "-l", (char *)0 };ret = execvp ("ls", cmd);
Variaciones wait()
pid_t wait(int *status)
pid_t waitpid(pid_t, int *status, int options)
Shell Unix
int main(int argc, char **argv){ while (1) { char *cmd = get_next_command(); int child_pid = fork(); if (child_pid == 0) { exec(cmd); // vea variaciones de exec panic(“exec failed!”); } else {
int st; waitpid(child_pid, &st, WIFEXITED(st)); } }}
Comunicación entre procesos
Usando señales SIGUSR1, SIGUSR2Ejemplo sigusuario.c
Usando PipesPermite la comunicación en un
sentido entre dos procesos• Int pipe(int fds[2])
Pipe en un proceso
pipe
Proceso de usuario
write fdread fd
-> Flujo de datos ->
kernel
Código que representa pipe en un proceso
#include <unistd.h>main() {
int pipefd[2], n;
char buff[100];
if(pipe(pipefd) < 0)cout<<“error con pipe”<<endl;
cout<<“read fd = %d, write fd = %d\n”, pipefd[0], pipefd[1]);if(write(pipefd[1], “hola yo mismo\n”, 14) != 14)
cerr<<“error con write”<<endl;
if ((n = read(pipefd[0], buff, sizeof(buff))) <=0 )cerr<<“error con read”<<endl;
write(1, buff, n); // 1 por salida estandar stdout
}
Pipe en proceso padre/hijo después de fork
pipe
-> Flujo de datos ->
write fdread fd
write fdread fd
forkProceso padre Proceso hijo
kernel
Comunicando padre con hijo en una dirección
pipe
-> Flujo de datos ->
write fdread fd
write fdread fd
forkProceso padre Proceso hijo
kernel
Usando dup2
int dup2(int oldfd, int newfd);Permite duplicar oldfd creado con otro
especificado en newfd, cerrando newfd primero si es necesario
Ejemplo usando dup2int main(int argc, char **argv){ int pipefd[2]; int pid; pipe(pipefd); pid = fork(); if (pid == 0){ // este es el hijo dup2(pipefd[1], 1); close(pipefd[1]); cout<<" hola papa como estas ...\n"; } else { char msg[100]; dup2(pipefd[0], 0); close(pipefd[1]); cin.getline(msg,100); int st; waitpid(pid, &st, WIFEXITED(st)); cout<<" msg en padre "<<msg<<endl; cout<<" ahh!! me hijo se acuerda de mi\n"; }}
Recommended