Advertisement
BiRabittoh

Esempio semafori e shared memory

Jan 4th, 2018
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.70 KB | None | 0 0
  1. /*
  2. * L'esempio consiste in un programma in cui vi sono un processo padre (P1) e un processo figlio (P2).
  3. * - P1 legge continuamente una stringa dalla memoria condivisa e ne stampa a video il testo.
  4. *   Quando legge il testo "end", P1 termina.
  5. *
  6. * - P2 scrive per 10 volte una stringa nella shared memory, alla fine scrive "end" e termina.
  7. *
  8. * Implementare il programma utilizzando i semafori per l'accesso esclusivo alla shared memory.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <sys/ipc.h>
  14. #include <sys/shm.h>
  15. #include <sys/types.h>
  16. #include <unistd.h>
  17. #include <string.h>
  18. #include <sys/sem.h>
  19. #include <sys/wait.h>
  20.  
  21. //#define EXIT_FAILURE 1
  22.  
  23. union semun { //va sempre inclusa per assicurare la portabilita' del codice
  24.     int val;
  25.     struct semid_ds *buf;
  26.     unsigned short *array;
  27. };
  28.  
  29. //prototipi funzioni
  30. void sem_set_val(int sem_id, int val);  //inizializza un semaforo
  31. int sem_down(int sem_id);               //down
  32. int sem_up(int sem_id);                 //up
  33. void sem_destroy(int sem_id);           //rimuove il semaforo
  34.  
  35. int main(){
  36.     pid_t pid;
  37.     int memid;
  38.     char * shared_memory;
  39.     char * message = "Test";
  40.     int i, sem_read, sem_write; //i due semafori servono per poter leggere o poter scrivere
  41.     sem_write = semget((key_t) 12345, 1, 0666 | IPC_CREAT); //inserire controlli sull'esito
  42.     sem_set_val(sem_write, 1); //scrittura subito permessa
  43.     sem_read = semget((key_t) 67890, 1, 0666 | IPC_CREAT); //inserire controlli sull'esito
  44.     sem_set_val(sem_read, 0); //lettura non permessa subito
  45.    
  46.     pid = fork(); //creazione processo figlio
  47.     switch(pid){
  48.         case -1:
  49.             perror("Error on fork\n");
  50.             exit(EXIT_FAILURE);
  51.             break;
  52.         case 0: //processo figlio
  53.             printf("Sono il figlio (%d)\n", getpid());
  54.             memid = shmget((key_t)9876541, 1024, 0666 | IPC_CREAT); //ottiene id shared memory
  55.             shared_memory = (char *)shmat(memid, NULL, 0); //fa l'attach della shared memory
  56.             sem_write = semget((key_t) 12345, 1, 0666 | IPC_CREAT); //ottiene id semaforo per scrittura
  57.             sem_read = semget((key_t) 67890, 1, 0666 | IPC_CREAT);
  58.            
  59.             while(i<5){ //cicla: ad ogni nuova scrittura, abilita la lettura
  60.                 if (!sem_down(sem_write))
  61.                     exit(EXIT_FAILURE); //down sul semaforo scrittura
  62.                 snprintf(shared_memory, 1024, "%d. %s", i, message); //Scrive sulla shared memory
  63.                 /*
  64.                 * int snprintf(char *str, size_t size, const char *format, ...); writes at most size bytes - including '\0' - to str
  65.                 */
  66.                 printf("Ho scritto nella shared memory = %s\n", shared_memory);
  67.                 i++;
  68.                 if (!sem_up(sem_read))
  69.                     exit(EXIT_FAILURE); //o abilita la lettura (successo) o esce
  70.             }
  71.            
  72.             if (!sem_down(sem_write))
  73.                 exit(EXIT_FAILURE); //down sul semaforo di scrittura
  74.             snprintf(shared_memory, 1024, "end"); //scrive la stringa "end" per terminare
  75.             printf("Ho scritto nella shared memory = %s\n", shared_memory);
  76.             if(!sem_up(sem_read))
  77.                 exit(EXIT_FAILURE); //o abilita la lettura (successo) o esce
  78.             printf("Ho finito di scrivere, il segmento non mi serve piu' (%d)\n", getpid());
  79.             shmdt(shared_memory); //scollega la shared memory
  80.             break;
  81.        
  82.         default: //codice del padre
  83.             printf("Sono il padre (%d)\n", getpid());
  84.             memid = shmget((key_t)9876541, 1024, 0666 | IPC_CREAT); //ottiene id shared memory
  85.             shared_memory = shmat(memid, NULL, 0); //fa l'attach della shared memory
  86.             if(!sem_down(sem_read))
  87.                 exit(EXIT_FAILURE); //down su semaforo lettura
  88.             while (strcmp(shared_memory, "end") != 0) { //cicla finche' non trova scritto "end"
  89.                 printf("Ho letto dalla shared memory = %s\n", shared_memory);
  90.                 fflush(stdout);
  91.                 if(!sem_up(sem_write))
  92.                     exit(EXIT_FAILURE); //abilita la scrittura o esce
  93.                 if(!sem_down(sem_read))
  94.                     exit("EXIT_FAILURE"); //down su semaforo scrittura (o forse lettura e la prof ha sbagliato)
  95.                 printf("Sono il padre, ho letto dalla shared memory = %s\n", shared_memory);
  96.             }
  97.             wait(NULL); //attende la terminazione del processo figlio
  98.            
  99.             shmdt(shared_memory); //fa la detach della shared memory
  100.             shmctl(memid, IPC_RMID, NULL); //rimuove la shared memory
  101.             sem_destroy(sem_read); //rimuove semaforo lettura
  102.             sem_destroy (sem_write); //rimuove semaforo scrittura
  103.             break;
  104.     }
  105. }
  106.  
  107. void sem_set_val(int sem_id, int val) {
  108.     union semun sem_un;
  109.     sem_un.val = val;
  110.     semctl(sem_id, 0, SETVAL, sem_un);
  111. }
  112.  
  113. int sem_down(int sem_id){
  114.     struct sembuf sem_buf;
  115.     sem_buf.sem_num = 0;
  116.     sem_buf.sem_op = -1;
  117.     sem_buf.sem_flg = SEM_UNDO;
  118.     if (semop(sem_id, &sem_buf, 1) == -1)
  119.         return 0;
  120.     return 1;
  121. }
  122.  
  123. int sem_up(int sem_id){
  124.     struct sembuf sem_buf;
  125.     sem_buf.sem_num = 0;
  126.     sem_buf.sem_op = 1;
  127.     sem_buf.sem_flg = SEM_UNDO;
  128.     if (semop(sem_id, &sem_buf, 1) == -1)
  129.         return 0;
  130.     return 1;
  131. }
  132.  
  133. void sem_destroy(int sem_id){
  134.     semctl(sem_id, 0, IPC_RMID);
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement