MÓDULO I - Conceptos Básicos y Programación Concurrente

Document Sample
MÓDULO I - Conceptos Básicos y Programación Concurrente Powered By Docstoc
					                  Programación Concurrente


                   Tema 1. Conceptos Básicos




Curso 2011/2012                          Grado en Ing. Informática
Tema 1. Conceptos Básicos

1. El concepto de proceso
     1.1. Gestión básica de procesos [Silber 3.1]
     1.2. Primitivas POSIX [Robb 2.5-2.7] [Rochk 5.1-5.7]
     1.3. Procesos e hilos [Silber 4.1, 4.3.1]

2. Fundamentos de prog. concurrente




Curso 2011/2012                               Grado en Ing. Informática
                                     Proceso | Prog. Concurrente



El concepto de
proceso

                                                        pila
   instr_1
   instr_2
   instr_3
      …                                             memoria
   instr_i    carga del ejecutable
                  en memoria
      …                                                datos
   instr_n
                                                       texto

   programa                                          proceso
Curso 2011/2012   Trp 3 de 41
                                                   Proceso | Prog. Concurrente



 Estados de un proceso


                       admitido
     nuevo                        interrupción                           terminado
                                                                salida


                     preparado                   en ejecución



                                                       espera E/S
             terminación E/S      en espera




Curso 2011/2012                                                             Trp 4 de 41
                                          Proceso | Prog. Concurrente



 Identificadores
        ID proceso
        #include <sys/types.h>
        #include <unistd.h>

        pid_t getpid (void); // ID del proceso
        pid_t getppid (void); // ID del proceso padre



        ID usuario
        #include <sys/types.h>
        #include <unistd.h>

        uid_t getuid (void); // ID del usuario
        uid_t geteuid (void); // ID del usuario efectivo




Curso 2011/2012                                                    Trp 5 de 41
                                          Proceso | Prog. Concurrente



 Creación de procesos :: fork()
                              proceso_A



                                fork()




                  proceso_A                 proceso_B
                    (cont.)                   (hijo)



                              hereda_de




Curso 2011/2012                                                    Trp 6 de 41
                                          Proceso | Prog. Concurrente



 Creación de procesos :: fork()
        fork()
        #include <sys/types.h>
        #include <unistd.h>

        pid_t fork (void); // 0 al hijo; ID del hijo al padre



        Ejemplo fork
        int *valor = malloc(sizeof(int));
        *valor = 0;
        fork();
        *valor = 13;
        printf("%ld: %d\n", (long)getpid(), *valor); // ¿?




Curso 2011/2012                                                    Trp 7 de 41
                                      Proceso | Prog. Concurrente



 Creación de procesos :: fork()
        Cadena de procesos
        #include <sys/types.h>                          1
        #include <unistd.h>
        #include <stdio.h>

        int main (void) {                               2
          int i = 1, n = 4;
          pid_t childpid;

            for (i = 1; i < n; i++)                     3
              // ?

             return 0;
        }                                               4




Curso 2011/2012                                                Trp 8 de 41
                                             Proceso | Prog. Concurrente



 Creación de procesos :: fork() + exec()
                                proceso_A



                                  fork()




                  proceso_A                  proceso_B
                    (cont.)                    (hijo)



                                               execl()


                                   SIGCHLD
                                                exit()

                    wait()                     zombie
                              Limpieza
                              tabla proc




Curso 2011/2012                                                       Trp 9 de 41
                                      Proceso | Prog. Concurrente



 Creación de procesos :: fork() + exec()
       Primitivas básicas
       #include <unistd.h>

       int execl (const char *path, const char *arg, ...);
       int execlp (const char *file, const char *arg, ...);
       int execle (const char *path, const char *arg, ...,
                   char *const envp[]);

       int execv (const char *path, char *const argv[]);
       int execvp (const char *file, char *const argv[]);
       int execve (const char *path, char *const argv[],
                   char *const envp[]);




Curso 2011/2012                                               Trp 10 de 41
                                       Proceso | Prog. Concurrente



 Creación de procesos :: fork() + exec()
   Ejemplo. Padre crea n hijos
        Padre
        // padre.c

        pid_t childpid;
        int n = atoi(argv[1]), i;

        for (i = 1; i <= n; i++)
          switch(childpid = fork()) {
          case 0:// Códigodelhijo.
            execl("./exec/hijo", "hijo", argv[1], NULL);
            break; // Para evitar entrar en el for.
          }
        // ¡Faltaría la espera del padre a los hijos!



Curso 2011/2012                                                Trp 11 de 41
                                       Proceso | Prog. Concurrente



 Creación de procesos :: fork() + exec()
        Hijo
        // hijo.c

        int main (int argc, char *argv[]) {
          hijo(argv[1]);
          return 0;
        }

        void hijo (const char *num_hermanos) {
          printf("¡Soy %ld y tengo %d hermanos!\n",
            (long)getpid(), atoi(num_hermanos) - 1);
        }




Curso 2011/2012                                                Trp 12 de 41
                                      Proceso | Prog. Concurrente



 Creación de procesos :: wait()
       Primitivas básicas
       #include <sys/types.h>
       #include <sys/wait.h>

       pid_t wait (int *status);
       pid_t waitpid (pid_t pid, int *status, int options);

       // BSD style
       pid_t wait3 (int *status, int options,
                    struct rusage *rusage);
       pid_t wait4 (pid_t pid, int *status, int options,
                    struct rusage *rusage);




Curso 2011/2012                                               Trp 13 de 41
                                        Proceso | Prog. Concurrente



 Creación de procesos :: signal()
       Primitivas básicas
       #include <sys/types.h>
       #include <signal.h>
       #include <unistd.h>

       typedef void (*sighandler_t)(int);
       sighandler_t signal (int signum,
                            sighandler_t handler);

       int kill (pid_t pid, int sig);

       int pause (void);




Curso 2011/2012                                                 Trp 14 de 41
                                       Proceso | Prog. Concurrente



 Creación de procesos :: wait()
        Padre
        // Se espera la terminación de los procesos...
        if (signal(SIGCHLD, esperar)== SIG_ERR) {
          fprintf(stderr, "No se esperó a un proceso.\n");
          exit(1);
        }

        // Manejo de Ctrol+C.
        if (signal(SIGINT,              controlador) ==
           SIG_ERR)       { fprintf(stderr, "Terminación
           incorrecta.\n"); exit(1);
        }

        while(1)  // Bucle infinito de espera.
         pause(); // A la espera de señales.



Curso 2011/2012                                                Trp 15 de 41
                                       Proceso | Prog. Concurrente



 Creación de procesos :: wait()
        Padre
        void esperar (int senhal) {
          int i;
          while (wait3(&i, WNOHANG, NULL) > 0);
        }

        void controlador (int senhal) {
          printf("\nCtrl+c capturada.\n");
          printf("Finalizando...\n\n");

            // Liberar recursos...
            printf("OK!\n");
            // Salida del programa.
            exit(0);
        }



Curso 2011/2012                                                Trp 16 de 41
                                  Proceso | Prog. Concurrente



 Procesos e hilos


  código       datos   archivos   código      datos       archivos

                                  registros   registros    registros
  registros              pila
                                     pila        pila         pila




       hebra




Curso 2011/2012                                           Trp 17 de 41
                                          Proceso | Prog. Concurrente



 Pthreads
   Especificación POSIX, no implementación
        Pthread
        #include <pthread.h>

        int pthread_create (pthread_t *thread,
                            const pthread_attr_t *attr,
                            void *(*start_routine) (void *),
                            void *arg);

        int pthread_join   (pthread_t thread, void **retval);




Curso 2011/2012                                                   Trp 18 de 41
                                            Proceso | Prog. Concurrente



 Pthreads
        Pthread
        int main (int argc, char *argv[]) {
          pthread_t tid;
          pthread_attr_t attr;

            if (argc != 2) {
              fprintf(stderr, "Uso: ./pthread <entero>\n");
              return -1;
            }

            pthread_attr_init(&attr); // Att predeterminados.
            // Crear el nuevo hilo.
            pthread_create(&tid, &attr, mi_hilo, argv[1]);
            pthread_join(tid, NULL);  // Esperar finalización.

            printf("Suma total: %d.\n", suma);
            return 0;
        }


Curso 2011/2012                                                     Trp 19 de 41
                                          Proceso | Prog. Concurrente



 Pthreads
        Pthread
        void *mi_hilo (void *valor) {
          int i, ls;
          ls = atoi(valor);
          i = 0, suma = 0;

            while (i <= ls)
             suma += (i++);

            pthread_exit(0);
        }



       Compilación
        $ gcc -lpthread pthread.c -o pthread
        $ ./pthread 7



Curso 2011/2012                                                   Trp 20 de 41
Tema 1. Conceptos Básicos

1. El concepto de proceso
2. Fundamentos de prog. concurrente
     2.1.   Problema del productor/consumidor [Silber 6.1]
     2.2.   La sección crítica [Silber 6.2-6.4]
     2.3.   Mecanismos básicos de sincron. [Silber 6.5, 6.7]
     2.4.   Interbloqueos y tratamiento del deadlock [Silber 7]




Curso 2011/2012                                Grado en Ing. Informática
                                         Proceso | Prog. Concurrente



 Buffer limitado

      while (1) {
        // Produce en nextP.
        while ((in + 1) % N == out);
          // No hacer nada.
        buffer[in] = nextP;
        in = (in + 1)%N;
      }

                    while (1) {
                      while (in == out);
                       // No hacer nada.
                      nextC = buffer[out];
                      out = (out + 1) % N;
                      // Consume nextC.
                    }




Curso 2011/2012                                                  Trp 22 de 41
                                            Proceso | Prog. Concurrente



 Productor/consumidor

      while (1) {                       cont++                cont--
        // Produce en nextP.
                                        r1 = cont             r2 = cont
        while (cont == N);
          // No hacer nada.             r1 = r 1 + 1          r2 = r 2 - 1
        buffer[in] = nextP;             cont = r 1            cont = r 2
        in = (in + 1)%N;
        cont++;
      }
                      while (1) {                        p:   r1 = cont
                        while (cont == 0);               p:   r 1 = r1 + 1
                         // No hacer nada.               c:   r2 = cont
                        nextC = buffer[out];             c:   r2 = r 2 - 1
                        out = (out + 1) % N;
                        cont--;                          p:   cont = r 1
                        // Consume nextC.                c:   cont = r 2
                      }



Curso 2011/2012                                                     Trp 23 de 41
                                  Proceso | Prog. Concurrente



 Sección crítica

   do {                         1. Exclusión mutua
                                2. Progreso
        SECCIÓN_ENTRADA
                                3. Espera limitada
              SECCIÓN_CRÍTICA


          SECCIÓN_SALIDA


             SECCIÓN_RESTANTE


   while(1);


Curso 2011/2012                                           Trp 24 de 41
                                  Proceso | Prog. Concurrente



 Sección crítica :: Sol 1 (2 proc)

   do {                         1. Exclusión mutua
       while (turn != i);
                                2. Progreso
                                3. Espera limitada
              SECCIÓN_CRÍTICA


             turn = j;


             SECCIÓN_RESTANTE


   while(1);


Curso 2011/2012                                           Trp 25 de 41
                                  Proceso | Prog. Concurrente



 Sección crítica :: Sol 2 (2 proc)

   do {                         1. Exclusión mutua
        flag[i] = true;         2. Progreso
        while (flag[j]);
                                3. Espera limitada
              SECCIÓN_CRÍTICA


        flag[i] = false;


             SECCIÓN_RESTANTE

   while(1);


Curso 2011/2012                                           Trp 26 de 41
                                        Proceso | Prog. Concurrente



 Sección crítica :: Peterson (2 proc)
   do {

        flag[i] = true;
        turn = j;
        while (flag[j] && turn == j);


              SECCIÓN_CRÍTICA
                                  1. Exclusión mutua
        flag[i] = false;
                                  2. Progreso
                                  3. Espera limitada
             SECCIÓN_RESTANTE

   while(1);


Curso 2011/2012                                                 Trp 27 de 41
                                  Proceso | Prog. Concurrente



Sección crítica :: Lamport (n proc)
 do {

    eleccion[i] = true;
    num[i] = max(num[0], ..., num[n]) + 1;
    elección[i] = false;
    for (j = 0; j < n; j++)
     while (elección[j]);
     while (num[j] != 0 && (num[j],    j)                 <
           (num[i],i));


          SECCIÓN_CRÍTICA
                              1. Exclusión mutua
        num[i] = 0;           2. Progreso
                 SEC_REST
                              3. Espera limitada
 while(1);
Curso 2011/2012   Trp 28 de 41
                                Proceso | Prog. Concurrente



 Sección crítica :: Hardware

   do {

        adquirir_cerrojo


              SECCIÓN_CRÍTICA
                                Operaciones
                                 atómicas
          liberar_cerrojo


             SECCIÓN_RESTANTE


   while(1);


Curso 2011/2012                                         Trp 29 de 41
                                  Proceso | Prog. Concurrente



 Sección crítica :: Swap
   do {

        key = true;
        while (key == true)
         swap(&lock, &key);


              SECCIÓN_CRÍTICA   swap
                                void swap (boolean *a,
                                           boolean *b)
          lock = false;         {
                                 // a := b
                                 // b := a
             SECCIÓN_RESTANTE   }

   while(1);


Curso 2011/2012                                           Trp 30 de 41
                                Proceso | Prog. Concurrente



 Sincronización :: Semáforos

   do {

            wait (sem)


              SECCIÓN_CRÍTICA
                                Operaciones
                                 atómicas
           signal (sem)


             SECCIÓN_RESTANTE


   while(1);


Curso 2011/2012                                         Trp 31 de 41
                                          Proceso | Prog. Concurrente



 Sincronización :: Semáforos

      while (1) {                              Memoria
        // Produce en nextP.
        wait (empty);                         compartida
        wait (mutex);
        // Guarda nextP en buffer.
        signal (mutex);
        signal (full);
      }                      while (1) {
                               wait (full);
                               wait (mutex);
                               // Rellenar nextC.
                               signal (mutex);
                               signal (empty);
                               // Consume nextC.
                             }




Curso 2011/2012                                                   Trp 32 de 41
                              Proceso | Prog. Concurrente



 Sincronización :: Paso de mensajes


                    Message
                   Message
                  Message



  Proceso 1                                           Proceso 2



                  Message
                   Message
                    Message




Curso 2011/2012                                       Trp 33 de 41
                                       Proceso | Prog. Concurrente



 Sincronización :: Paso de mensajes

    Proceso 1                        Proceso 2
    while (1) {                       while (1) {
      // W_previo_1                     // W_previo_2
      send ('*', P2)                    receive (&msg, P1)
      // W_restante_1                   // W_restante_2
    }                                 }




                  Sincronización (P2 no avanza
                   hasta que no recibe de P1)


Curso 2011/2012                                                Trp 34 de 41
                                         Proceso | Prog. Concurrente



 Sincronización :: Monitores

                           Datos
                        compartidos
                    x
Condiciones
                    y



                        Operaciones

                            Código
                        inicialización



                  Operaciones con exclusión mutua
                         dentrodelmonitor

Curso 2011/2012                                                  Trp 35 de 41
                                        Proceso | Prog. Concurrente



 Interbloqueos

                                 R1
    Condicionesde                                                  R2
       Coffman
● Exclusión mutua
● Retener y esperar

● No apropiación

● Espera circular
                            P1
                                                         P2

                      Esperando R2...
                                                 Esperando R1...




Curso 2011/2012                                                    Trp 36 de 41
                                   Proceso | Prog. Concurrente



 Grafos de asignación de recursos
                              R1                       R3


 P={P 1 , P2, P 3}
 R={R1, R 2, R 3, R 4}
 E={P1-->R 1 ,
    R 1-->P 2,           P1                P2                    P3

    ...}




                              R2                       R4


Curso 2011/2012                                             Trp 37 de 41
                                  Proceso | Prog. Concurrente



 Grafos de asignación de recursos

           R1          R3

                                                                P2

                                           R1



    P1            P2        P3   P1                             P3




                                                                P4


           R2          R4                  R2




Curso 2011/2012                                           Trp 38 de 41
                                                                        Proceso | Prog. Concurrente



 Tratamiento del deadlock
                                       Métodos tratamiento deadlock




            Impedir o evitar                        Detectar y recuperar                          Ignorar



                                                                        1
     Prevención            Evasión                                                                  2
                                                        Info sobre el
                                                                                      Algoritmo
                                                          estado de
                                                                                      detección
                                                          recursos




     Evitar las 4           Política                                                                3
     condiciones          asignación                                                   Algoritmo
       Coffman             recursos                                                  recuperación




Curso 2011/2012                                                                                     Trp 39 de 41
                                   Proceso | Prog. Concurrente



 Evasión del deadlock

                     Algoritmo
                    del banquero

                            Peticiones de recursos




    Algoritmo de       ¿Estado           No
                                                         Deshacer
     seguridad         seguro?


                            Sí



                   Asignar recursos



Curso 2011/2012                                            Trp 40 de 41
 Tema 1. Conceptos Básicos

 1. El concepto de proceso
 2. Fundamentos de prog. concurrente




Curso 2011/2012               Grado en Ing. Informática

				
DOCUMENT INFO
Shared By:
Tags:
Stats:
views:110
posted:8/6/2012
language:
pages:43