Advertisement
Vladpepe

Untitled

May 17th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.94 KB | None | 0 0
  1. 16 LUGLIO 2014
  2. La parte in C accetta un numero variabile di parametri N+1 (maggiore o uguale a 2, da controllare) che
  3. rappresentano i primi N i nomi assoluti di file F1...FN e l’ultimo la lunghezza in linee dei file (X, da non
  4. controllare). Il processo padre deve generare N processi figli (P0 … PN-1): ogni processo figlio è associato al
  5. corrispondente file Fi. Ognuno di tali processi figli esegue concorrentemente, leggendo tutte le X linee del file
  6. associato Fi: per ogni linea letta, il figlio Pi deve selezionare il primo carattere e quindi comunicare questa
  7. informazione. In particolare, i processi figli e il processo padre devono attenersi ad uno schema di
  8. comunicazione a pipeline; il figlio P0 comunica con il figlio P1 etc. fino al figlio PN-1 che comunica con il
  9. padre; questo schema a pipeline deve essere ripetuto per ogni linea di ogni file e deve prevedere l’invio in avanti
  10. di un array di caratteri (primiCar) di grandezza pari al numero di linee dei file; il primo figlio P0, dopo aver
  11. completato la lettura della linea corrente letta dal file associato F1, inserisce in primiCar al primo posto il primo
  12. carattere della linea corrente e quindi invia primiCar al figlio P1; quindi ogni figlio Pi (a parte P0) deve
  13. ricevere primiCar e quindi deve inserire, dopo aver completato la lettura della linea corrente letta dal file
  14. associato Fi, in primiCar al posto corretto il primo carattere della linea corrente e quindi invia avanti primiCar
  15. al figlio successivo, fino a PN-1 che la invia al processo padre. Quindi, al processo padre devono arrivare tanti
  16. array primiCar quante sono le linee dei file letti dai processi figli P0 … PN-1. Il padre ha il compito di
  17. stampare su standard output tutte le informazioni ricevute dal processo PN-1: in particolare, deve essere
  18. stampato -per ogni linea- un contatore di linea e quindi i primi caratteri letti da ogni processo figlio riportando
  19. anche -per ogni carattere- l’indice del processo che ha effettuato la lettura e il nome del file da cui si è letto tale
  20. carattere.
  21. Al termine, ogni processo figlio Pi deve ritornare al padre l’ultimo carattere selezionato dal proprio file associato
  22. Fi e il padre deve stampare su standard output il PID di ogni figlio e il valore ritornato.
  23.  
  24. /* Soluzione della parte C del compito del 16 Luglio 2014 */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #include <sys/wait.h>
  29. #include <sys/stat.h>
  30. #include <string.h>
  31. #include <fcntl.h>
  32.  
  33. typedef int pipe_t[2];
  34.  
  35. int main (int argc, char **argv)
  36. {
  37. int N;      /* numero di file */
  38. int X;      /* numero di linee */
  39. int pid;    /* pid per fork */
  40. pipe_t *pipes;  /* array di pipe usate a pipeline da primo figlio, a secondo figlio .... ultimo figlio e poi a padre: ogni processo legge dalla pipe i-1 e scrive sulla pipe i */
  41. int i,j;    /* contatori */
  42. int fd;     /* file descriptor */
  43. int pidFiglio, status, ritorno; /* per valore di ritorno figli */
  44. char *primiCar;     /* array dinamico di caratteri che i figli si passeranno in pipeline e che arriverà al padre */
  45. char ch, chprimo;   /* carattere letto da linea e carattere da inserire nell'array */
  46. int nr,nw;      /* variabili per salvare valori di ritorno di read e write da/su pipe */
  47. /* int linee = 1;      serve per mantenere il numero corrente della linea e e' stata usata solo nelle stampe di controllo */
  48.  
  49. if (argc < 3)
  50. {
  51. printf("Errore numero di parametri\n");
  52. exit(1);
  53. }
  54.  
  55. X = atoi(argv[argc-1]);
  56. printf("Numero di linee %d\n", X);
  57. /* controllo non richiesto, ma inserito per sicurezza */
  58. if (X < 0)
  59. {
  60.     printf("Errore numero linee: non maggiore di zero\n");
  61.     exit(2);
  62. }
  63.  
  64. N = argc-2;
  65. printf("Numero di processi da creare %d\n", N);
  66.  
  67. /* allocazione primiCar: la fa il padre e tutti i figli lo otterranno per copia */
  68. if ((primiCar=(char *)malloc(N*sizeof(char))) == NULL)
  69. {
  70.     printf("Errore allocazione primiCar\n");
  71.     exit(3);
  72. }
  73.  
  74. /* allocazione pipe */
  75. if ((pipes=(pipe_t *)malloc(N*sizeof(pipe_t))) == NULL)
  76. {
  77.     printf("Errore allocazione pipe\n");
  78.     exit(4);
  79. }
  80.  
  81. /* creazione pipe */
  82. for (i=0;i<N;i++)
  83.     if(pipe(pipes[i])<0)
  84.     {
  85.         printf("Errore creazione pipe\n");
  86.         exit(5);
  87.     }
  88.  
  89. /* creazione figli */
  90. for (i=0;i<N;i++)
  91. {
  92.     if ((pid=fork())<0)
  93.     {
  94.         printf("Errore creazione figli\n");
  95.         exit(6);
  96.     }
  97.     else if (pid==0)
  98.     { /* codice figlio */
  99.     printf("Sono il figlio %d\n", getpid());
  100.     /* chiusura pipes inutilizzate */
  101.     for (j=0;j<N;j++)
  102.     {
  103.         if (j!=i)
  104.             close (pipes[j][1]);
  105.         if ((i == 0) || (j != i-1))
  106.             close (pipes[j][0]);
  107.     }
  108.  
  109.     /* apertura file */
  110.     if ((fd=open(argv[i+1],O_RDONLY))<0)
  111.     {
  112.     printf("Impossibile aprire il file %s\n", argv[i+1]);
  113.     exit(7);
  114.     }
  115.     j = 0;
  116.     while(read(fd,&ch,1)>0)
  117.     {
  118.         if (j == 0) /* se e' il primo carattere della linea allora lo salviamo in chprimo */
  119.             {
  120.             chprimo = ch;
  121.             /* stampa di controllo
  122.                 printf("processo di indice %d ha salvato il carattere %c per la linea %d\n",i, chprimo, linee);
  123.             */
  124.           }
  125.    
  126.         /* controllo fine linea */
  127.         if (ch == '\n')  /* siamo a fine linea */
  128.             {
  129.             /* linee++; introdotto solo per stampe di controllo */
  130.             if (i!=0) /* il primo figlio NON deve leggere dal figlio precedente l'array */
  131.                 {
  132.                 nr=read(pipes[i-1][0],primiCar, N);
  133.                 if (nr!=N)
  134.                          {
  135.                             printf("Errore in lettura da pipe[%d]\n",i);
  136.                             exit(8);
  137.                          }
  138.             }
  139. /* in ogni modo, quindi sia per il primo figlio che per gli altri, deve essere inserito il carattere al posto giusto */
  140.             primiCar[i] = chprimo;
  141.             /* comunicazione primiCar al figlio seguente  */
  142.             nw=write(pipes[i][1], primiCar, N);
  143.             if (nw!=N)
  144.             {
  145.                 printf("Errore in scrittura da pipe[%d]\n",i);
  146.                 exit(9);
  147.             }
  148.             j = 0; /* riazzeriamo il conteggio dei caratteri della linea */
  149.         }
  150.         else
  151.             {
  152.                 j++; /* incrementiamo il conteggio dei caratteri della linea */
  153.             }  
  154.  
  155.     }  
  156.     exit(chprimo);
  157.     }
  158. } /* fine for */
  159.  
  160. /* codice del padre */
  161. /* chiusura pipe: tutte meno l'ultima in lettura */
  162. for(i=0;i<N;i++)
  163.     {
  164.     close (pipes[i][1]);
  165.     if (i != N-1) close (pipes[i][0]);
  166.     }
  167.  
  168. /* il padre deve leggere X strutture, tante quante sono le linee lette dai figli */
  169. for(j=0;j<X;j++)
  170.     {
  171.     read(pipes[N-1][0], primiCar, N);
  172.     printf("Ricevuto per la linea %d i seguenti primi caratteri:\n", j+1); /* incrementiamo j in modo da rendere piu' chiaro a che linea ci stiamo riferendo */
  173.     for(i=0;i<N;i++)
  174.             printf("Carattere %c ricevuto dal processo di indice %d per il file %s\n", primiCar[i], i, argv[i+1]);
  175.     }
  176.  
  177. /* Il padre aspetta i figli */
  178. for (i=0; i < N; i++)
  179.         {
  180.         pidFiglio = wait(&status);
  181.         if (pidFiglio < 0)
  182.                 {
  183.                 printf("Errore in wait\n");
  184.                 exit(10);
  185.                 }
  186.  
  187.         if ((status & 0xFF) != 0)
  188.                 printf("Figlio con pid %d terminato in modo anomalo\n", pidFiglio);
  189.         else
  190.                 { ritorno=(int)((status >> 8) & 0xFF);
  191.                   printf("Il figlio con pid=%d ha ritornato %c\n", pidFiglio, ritorno);
  192.                 }
  193.         }
  194. return(0);
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement