Procesos

8,052 views

Published on

Procesos

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
8,052
On SlideShare
0
From Embeds
0
Number of Embeds
63
Actions
Shares
0
Downloads
269
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Procesos

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

×