Anteprima
Vedrai una selezione di 10 pagine su 41
Sistemi operativi - Appunti Pag. 1 Sistemi operativi - Appunti Pag. 2
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 6
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 11
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 16
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 21
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 26
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 31
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 36
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Sistemi operativi - Appunti Pag. 41
1 su 41
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

Codice di sincronizzazione tra processi

SIGNAL(MUTEX);value++; //Avanza nell'alfabetosleep(5); //Simula un tempo di produzione}exit(0); //Il figlio Scrittore termina correttamente}//----- GENERAZIONE FIGLIO LETTORE -----pid=fork();if (pid==-1) {perror("Impossibile creare un nuovo processo\n"); //In caso di errore...exit(-1);} else if (!pid) { //Codice del figlio Lettoreprintf("Sono il Lettore, PID = %d\n", getpid());sleep(3); //Attende prima di tentare di leggerefor(i=0; i

  • Il consumo del buffer di memoria comune (allocato dal processo padre) da parte del processo produttore non può avvenire se non dopo che il contenuto vi abbia depositato un nuovo elemento e all'atto del consumo il contenuto del buffer viene cancellato.
  • Il processo produttore non può depositare nel buffer di memoria comune un nuovo elemento se il precedente non è stato ancora consumato.
  • Il processo consumatore non può consumare un elemento dal buffer di memoria comune se non è stato ancora depositato un nuovo elemento dal processo produttore.
  • A garanzia
    <pre>
    <code>
    della consistenza del contenuto del buffer condiviso, eproduttore devono accedervi in mutua esclusione.→ Semafori.H (L'implementazione è quella indicata per il programma I)#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>void Init_Sem(int, int); //Inizializza Semaforovoid Wait_Sem(int, int); //Wait su Semaforovoid Signal_Sem(int, int); //Signal su Semaforoint Awaiting_Sem(int, int); //Restituisce il numero di processi in attesa su Semaforo→ Programma II.C#include <stdio.h>#include <sys/shm.h>#include <sys/wait.h>#include "semafori.h"#define DIM 1 //Dimensione dell'area di memoria condivisa#define NUM_OPS 4 //Numero di produzioni/consumi#define SPAZIO_DISPONIBILE 0 //Definizione di MACRO per l'accesso ai semafori#define MESSAGGIO_DISPONIBILE 1#define INITIALIZE(S,V) Init_Sem(ID_Sem,S,V)#define WAIT(S) Wait_Sem(ID_Sem,S)#define SIGNAL(S) Signal_Sem(ID_Sem,S)void main() {pid_t pid; //Variabili
    </code>
    </pre>
    locali
    int i;
    char value='A';
    int status;
    
    //----- ALLOCAZIONE BUFFER DI MEMORIA CONDIVISA -----
    key_t Key_Buf=IPC_PRIVATE; //Chiave del buffer
    int ID_Buf; //Identificatore del buffer
    char* Ptr_Buf; //Puntatore al buffer
    
    ID_Buf=shmget(Key_Buf, DIM, IPC_CREAT|0664); //Viene allocato un segmento di memoria di dimensione almeno
                                                 //pari DIM, gli viene associato un ID e viene creata una
                                                 //struttura dati ausiliaria che consenta di gestirlo
                                                 //RW per User, RW per Gruppo, R only per Others
    if (ID_Buf==-1) {
        perror("SHMGET\n"); //In caso di errore...
        exit(-1);
    }
    
    Ptr_Buf=shmat(ID_Buf, 0, 0); //Il segmento allocato viene annesso al segmento dati
                                 //del processo al primo indirizzo disponibile così come
                                 //specificato dal sistema
    if (Ptr_Buf==(char*)-1) {
        perror("SHMAT\n"); //In caso di errore...
        shmctl(ID_Buf, IPC_RMID, 0); //Rimuove l'ID della Shared Memory indicata, dealloca
                                     //il segmento di memoria corrispondente ed elimina le
                                     //strutture dati ad esso associate
        exit(-1);
    }
    
    //-----
    
    
    <key_t> Key_Sem=IPC_PRIVATE; //Chiave del semaforo/i
    <int> ID_Sem; //Identificatore del semaforo/i
    ID_Sem=semget(Key_Sem, 2, IPC_CREAT|0664); //Viene allocato un gruppo di semafori di cardinalità 2,
    //viene associato al gruppo un ID e viene creata una
    //struttura dati ausiliaria che consenta di gestirlo
    //RW per User, RW per Gruppo, R only per Others
    if (ID_Sem==-1) {
        perror("SEMGET\n"); //In caso di errore...
        exit(-1);
    }
    
    INITIALIZE(SPAZIO_DISPONIBILE,1); //Setta SPAZIO_DISPONIBILE a 1
    INITIALIZE(MESSAGGIO_DISPONIBILE,0); //Setta MESSAGGIO_DISPONIBILE a 0
    
    //----- GENERAZIONE FIGLIO PRODUTTORE -----
    pid=fork(); //Generazione del figlio Produttore
    if (pid==-1) {
        perror("Impossibile creare un nuovo processo\n"); //In caso di errore...
        exit(-1);
    } else if (!pid) { //Codice del figlio Produttore
        printf("Sono il Produttore, PID = %d\n", getpid());
        for (i=0; i<NUM_OPS; i++) {
            WAIT(SPAZIO_DISPONIBILE);
            printf("Produco: %c\n", value);
    
    
    
    //Sezione Critica di PRODUZIONE
    Ptr_Buf=value;
    SIGNAL(MESSAGIO_DISPONIBILE);
    value++; //Avanza nell'alfabeto
    sleep(5); //Simula un tempo di produzione
    exit(0); //Il figlio Produttore termina correttamente
    
    //----- GENERAZIONE FIGLIO CONSUMATORE -----
    pid=fork();
    if (pid==-1) {
        perror("Impossibile creare un nuovo processo\n"); //In caso di errore...
        exit(-1);
    } else if (!pid) {
        //Codice del figlio Consumatore
        printf("Sono il Consumatore, PID = %d\n", getpid());
        sleep(3); //Attende prima di tentare di consumare
        for(i=0; i
    

    terminato!

    pid);}//----- RILASCIO MEMORIA CONDIVISA E SEMAFORO -----shmctl(ID_Buf, IPC_RMID, 0);semctl(ID_Sem, 0, IPC_RMID);}

    5Problemi di cooperazione nel modello a memoria comune

    Scrivere un'applicazione concorrente che implementi il problemaIII)Produttore/Consumatore nella variante che prevede più produttori e consumatori che comunicano attraverso un pool di buffer di memoria gestito come vettore circolare.

    Descrizione: Il programma seguente implementa il problema dei Produttori/Consumatori (più di uno) nel caso in cui essi si contendano un pool di buffer organizzato come coda circolare (inserimento in coda, prelievo in testa), posto che ad essi si applichino i seguenti vincoli:

    • consumoil di un singolo buffer di memoria comune (l'insieme del pool è allocato dal processo padre) daprocesso consumatore processo produttoreparte di un non può avvenire se non dopo che almeno un vicontenuto, consumo contenutoabbia depositato un e
    all'atto del tale viene cancellato.
    <ul>
      <li> processo produttore contenuto non può depositare in un buffer di memoria comune un nuovo se non è disponibile alcun buffer libero.</li>
      <li> processi consumatori processiA garanzia della consistenza del contenuto del buffer condiviso, e produttori, globalmente, devono accedere al singolo buffer in mutua esclusione, tuttavia l'accesso al pool di buffer nella sua totalità avviene comunque in concorrenza→ Semafori.</li>
    </ul>
    
    <h3>Semafori.h</h3>
    <pre>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    
    void Init_Sem(int, int); //Inizializza Semaforo
    void Wait_Sem(int, int); //Wait su Semaforo
    void Signal_Sem(int, int); //Signal su Semaforo
    int Awaiting_Sem(int, int); //Restituisce il numero di processi in attesa su Semaforo
    </pre>
    
    <h3>Prod_Cons_Queue.H</h3>
    <pre>
    #include <stdio.h>
    #include "semafori.h"
    #define DIM_QUEUE 4 //Cardinalità della Coda
    </pre>
    
    
    circolare#define VUOTO 0 //Stati del singolo buffer della Coda circolare#define IN_USO 1#define PIENO 2typedef struct { //Definizione della Coda circolarechar buffer[DIM_QUEUE];char stato[DIM_QUEUE]; //VUOTO, IN_USO o PIENOint testa;int coda;} Queue;void Init_Queue(Queue*); //Inizializza la Coda circolarevoid Init_Semafori_Queue(int); //Inizializza i semaforiint Richiesta_Produzione_Queue(Queue*, int); //Richiesta di un buffer libero per la produzionevoid Produzione_Queue(int, char, Queue*); //Produzione di un carattere nella Coda circolarevoid Rilascio_Produzione_Queue(int, Queue*, int); //Rilascio di un buffer pienoint Richiesta_Consumo_Queue(Queue*, int); //Richiesta di un buffer pieno per il consumochar Consumo_Queue(int, Queue*); //Consumo di un carattere dalla Coda circolarevoid Rilascio_Consumo_Queue(int, Queue*, int); //Rilascio di un buffer vuoto→ Prod_Cons_Queue.C#include “prod_cons_queue.h”#define SPAZIO_DISPONIBILE 0 //Definizione di MACRO per
    
    
    l'accesso ai semafori
    #define MESSAGGIO_DISPONIBILE 1
    #define MUTEX_PROD 2
    #define MUTEX_CONS 3
    #define INITIALIZE(S,V) Init_Sem(ID_Sem,S,V)
    #define WAIT(S) Wait_Sem(ID_Sem,S)
    #define SIGNAL(S) Signal_Sem(ID_Sem,S)
    
    void Init_Queue(Queue* Q) {
        for(int i=0; i<DIM_QUEUE; i++)
            Q->stato[i]=VUOTO;
        Q->testa=0;
        Q->coda=0;
    }
    
    void Init_Semafori_Queue(int ID_Sem) {
        INITIALIZE(SPAZIO_DISPONIBILE,DIM_QUEUE);
        INITIALIZE(MESSAGGIO_DISPONIBILE,0);
        INITIALIZE(MUTEX_PROD,1);
        INITIALIZE(MUTEX_CONS,1);
    }
    
    int Richiesta_Produzione_Queue(Queue* Q, int ID_Sem) {
        WAIT(SPAZIO_DISPONIBILE);
        WAIT(MUTEX_PROD);
        int i=Q->coda;
        do {
            Q->coda=(Q->coda+1) % DIM_QUEUE;
        } while (Q->stato[Q->coda]!=VUOTO);
        Q->stato[i]=IN_USO;
        SIGNAL(MUTEX_PROD);
        printf("Buffer %d in uso\n", i);
        return i;
    }
    
    void Produzione_Queue(int i, char value, Queue* Q) {
        Q->buffer[i]=value;
        printf("Ho prodotto %c nel buffer %d\n", value, i);
    }
    
    void Rilascio_Produzione_Queue(int i, Queue* Q, int ID_Sem)
    
    {Q->stato[i]=PIENO;printf("Buffer %d riempito\n", i);SIGNAL(MESSAGGIO_DISPONIBILE);}
    int Richiesta_Consumo_Queue(Queue* Q, int ID_Sem) {
        WAIT(MESSAGGIO_DISPONIBILE);
        WAIT(MUTEX_CONS);
        int i=Q->testa;
        while (Q->stato[i]!=PIENO) {
            i=(i+1) % DIM_QUEUE;
        }
        if (i==Q->testa)
            Q->testa=(Q->testa+1) % DIM_QUEUE;
    Q
    
    Dettagli
    Publisher
    A.A. 2007-2008
    41 pagine
    SSD Ingegneria industriale e dell'informazione ING-INF/05 Sistemi di elaborazione delle informazioni

    I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Chiakka87 di informazioni apprese con la frequenza delle lezioni di Sistemi operativi e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli studi di Napoli Federico II o del prof De Carlini Ugo.