ENUNCIADO

Consiste en programar un padre que tiene diez hijos. Los hijos imprimen por pantalla "Soy el hijo número n y mi PID es PID". n será el número de orden del hijo en cuestión y PID será su PID. El padre esperará a que sus hijos acaben antes de terminar. Haced sólo un código fuente en C. El número de hijo lo pasará el padre al hijo mediante una tubería sin nombre creada al efecto.

COMENTARIOS

Puesto compartido:
  1. De Sagolpan y Satan (0.125 ptos.): usan una sola tubería para "hablar" con los hijos. El precio que hay que pagar es que el padre tiene un hijo, habla con él y espera a que muera. Así es como logramos que otro hijo no se adelante y lea lo que no le corresponda (problema de sincronización).
    #define _HPUX_SOURCE
    
    #include <sys/ipc.h>
    #include <stdio.h>
    
    int main(void)
    {
       int tuberia[2], hijos, devuelto;
       char cadena[2];
    
       if(pipe(tuberia)==-1)
       {
          perror("pipe");
          return -1; /* ¡¡¡QUE NO!!! Al S.O. se le devuelve algo ≥ 0 */
       }
    
       for(hijos = 1; hijos <= 10; hijos++)
       {
          switch(fork()) {
             case -1: perror("fork");
                      return -1; /* ¡¡¡QUE NO!!! Al S.O. se le devuelve algo ≥ 0 */
             case 0: if(read(tuberia[0], cadena, 2) == -1)
                     {
                        perror("read");
                        return -1; /* ¡¡¡QUE NO!!! Al S.O. se le devuelve algo ≥ 0 */
                     }
                     fprintf(stdout, "Soy el hijo %s y mi PID es %d.\n", 
                                     cadena, getpid()); 
                     return 0;
             default: sprintf(cadena, "%d", hijos);
                      if(write(tuberia[1], cadena, 2) == -1)
                      {
                         perror("write");
                         return -1; /* ¡¡¡QUE NO!!! Al S.O. se le devuelve algo ≥ 0 */
                      }
                      wait(&devuelto); /* La madre del cordero. */
             }
       }
       return 0;
    }           
  2. De Goku y Son Gohan (0.125 ptos.): usan una tubería diferente para cada hijo. Así no hace falta sincronizar. La espera se produce al final. Esta fue mi idea original.
    #define _HPUX_SOURCE
    
    #define NUM_HIJOS 10
    
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    void hijo(void);
    int tuberia[2]; /* ¡¡¡OJO!!! Variable global innecesaria */
    
    
    int main(int argc,char *argv[])
    {
       int i,retorno,todos=1;
       if(argc!=1)
          {
          fprintf(stderr,"Uso: %s\n\n",argv[0]);
          return 1;
          }
    
       if(pipe(tuberia)==-1)
          {
          perror("pract7-1:pipe");
          return 2;
          }
    
       for(i=1;<=NUM_HIJOS;i++)
          {
          switch(fork())
             {
             case -1:
                perror("pract7-1:fork");
                return 3;
             case 0:
                hijo();
             default:
               if(write(tuberia[1],&i,sizeof(int))==-1)
                   { /* Pasan los datos en binario (frente ASCII). Comparad con arriba. */
                   perror("pract7-1:write");
                   return 4;
                   }
             }
          }
    
       for(i=1;i<=NUM_HIJOS;i++)
          {
          if(wait(&retorno)==-1)
            {
            perror("pract7-1:wait");
            return 5;
            }
    
          if(WIFEXITED(retorno))
             if(WEXITSTATUS(retorno)!=0)
                {
                printf("El hijo numero %d ha tenido un error.\n",i);
                todos=0;
                }
          }
    
       if(todos)
          printf("\n Todos mis hijos han acabado sin errores\n");
    
       close(tuberia[0]); /* ¡Bien! Las tuberías también se cierran. */
       close(tuberia[1]); /* Aquí da un poco igual, pues el proceso va a morir. */
       return 0;
    } 
    
    void hijo(void)
    {
       int pid,num_hijo;
    
       if(read(tuberia[0],&num_hijo,sizeof(int))==-1)
          {
          perror("pract7-1:read");
          exit(6);
          }
    
       if(num_hijo==1)
          if(system("clear")==-1)
             {
             perror("pract-1:system");
             exit(7);
             }
    
       pid=getpid();
       if(pid==-1)
          {
          perror("pract7-1:getpid");
          exit(8);
          }
    
       printf("\n Soy el numero de hijo %d y mi pid es %d \n",num_hijo,pid);
       close(tuberia[0]);
       close(tuberia[1]);
       exit(0);
    }       



© 2000 Guillermo González Talaván.