Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * L'esempio consiste in un programma in cui vi sono un processo padre (P1) e un processo figlio (P2).
- * - P1 legge continuamente una stringa dalla memoria condivisa e ne stampa a video il testo.
- * Quando legge il testo "end", P1 termina.
- *
- * - P2 scrive per 10 volte una stringa nella shared memory, alla fine scrive "end" e termina.
- *
- * Implementare il programma utilizzando i semafori per l'accesso esclusivo alla shared memory.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/sem.h>
- #include <sys/wait.h>
- //#define EXIT_FAILURE 1
- union semun { //va sempre inclusa per assicurare la portabilita' del codice
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- };
- //prototipi funzioni
- void sem_set_val(int sem_id, int val); //inizializza un semaforo
- int sem_down(int sem_id); //down
- int sem_up(int sem_id); //up
- void sem_destroy(int sem_id); //rimuove il semaforo
- int main(){
- pid_t pid;
- int memid;
- char * shared_memory;
- char * message = "Test";
- int i, sem_read, sem_write; //i due semafori servono per poter leggere o poter scrivere
- sem_write = semget((key_t) 12345, 1, 0666 | IPC_CREAT); //inserire controlli sull'esito
- sem_set_val(sem_write, 1); //scrittura subito permessa
- sem_read = semget((key_t) 67890, 1, 0666 | IPC_CREAT); //inserire controlli sull'esito
- sem_set_val(sem_read, 0); //lettura non permessa subito
- pid = fork(); //creazione processo figlio
- switch(pid){
- case -1:
- perror("Error on fork\n");
- exit(EXIT_FAILURE);
- break;
- case 0: //processo figlio
- printf("Sono il figlio (%d)\n", getpid());
- memid = shmget((key_t)9876541, 1024, 0666 | IPC_CREAT); //ottiene id shared memory
- shared_memory = (char *)shmat(memid, NULL, 0); //fa l'attach della shared memory
- sem_write = semget((key_t) 12345, 1, 0666 | IPC_CREAT); //ottiene id semaforo per scrittura
- sem_read = semget((key_t) 67890, 1, 0666 | IPC_CREAT);
- while(i<5){ //cicla: ad ogni nuova scrittura, abilita la lettura
- if (!sem_down(sem_write))
- exit(EXIT_FAILURE); //down sul semaforo scrittura
- snprintf(shared_memory, 1024, "%d. %s", i, message); //Scrive sulla shared memory
- /*
- * int snprintf(char *str, size_t size, const char *format, ...); writes at most size bytes - including '\0' - to str
- */
- printf("Ho scritto nella shared memory = %s\n", shared_memory);
- i++;
- if (!sem_up(sem_read))
- exit(EXIT_FAILURE); //o abilita la lettura (successo) o esce
- }
- if (!sem_down(sem_write))
- exit(EXIT_FAILURE); //down sul semaforo di scrittura
- snprintf(shared_memory, 1024, "end"); //scrive la stringa "end" per terminare
- printf("Ho scritto nella shared memory = %s\n", shared_memory);
- if(!sem_up(sem_read))
- exit(EXIT_FAILURE); //o abilita la lettura (successo) o esce
- printf("Ho finito di scrivere, il segmento non mi serve piu' (%d)\n", getpid());
- shmdt(shared_memory); //scollega la shared memory
- break;
- default: //codice del padre
- printf("Sono il padre (%d)\n", getpid());
- memid = shmget((key_t)9876541, 1024, 0666 | IPC_CREAT); //ottiene id shared memory
- shared_memory = shmat(memid, NULL, 0); //fa l'attach della shared memory
- if(!sem_down(sem_read))
- exit(EXIT_FAILURE); //down su semaforo lettura
- while (strcmp(shared_memory, "end") != 0) { //cicla finche' non trova scritto "end"
- printf("Ho letto dalla shared memory = %s\n", shared_memory);
- fflush(stdout);
- if(!sem_up(sem_write))
- exit(EXIT_FAILURE); //abilita la scrittura o esce
- if(!sem_down(sem_read))
- exit("EXIT_FAILURE"); //down su semaforo scrittura (o forse lettura e la prof ha sbagliato)
- printf("Sono il padre, ho letto dalla shared memory = %s\n", shared_memory);
- }
- wait(NULL); //attende la terminazione del processo figlio
- shmdt(shared_memory); //fa la detach della shared memory
- shmctl(memid, IPC_RMID, NULL); //rimuove la shared memory
- sem_destroy(sem_read); //rimuove semaforo lettura
- sem_destroy (sem_write); //rimuove semaforo scrittura
- break;
- }
- }
- void sem_set_val(int sem_id, int val) {
- union semun sem_un;
- sem_un.val = val;
- semctl(sem_id, 0, SETVAL, sem_un);
- }
- int sem_down(int sem_id){
- struct sembuf sem_buf;
- sem_buf.sem_num = 0;
- sem_buf.sem_op = -1;
- sem_buf.sem_flg = SEM_UNDO;
- if (semop(sem_id, &sem_buf, 1) == -1)
- return 0;
- return 1;
- }
- int sem_up(int sem_id){
- struct sembuf sem_buf;
- sem_buf.sem_num = 0;
- sem_buf.sem_op = 1;
- sem_buf.sem_flg = SEM_UNDO;
- if (semop(sem_id, &sem_buf, 1) == -1)
- return 0;
- return 1;
- }
- void sem_destroy(int sem_id){
- semctl(sem_id, 0, IPC_RMID);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement