|
Appunti informatica |
|
Visite: 1160 | Gradito: | [ Picolo appunti ] |
Leggi anche appunti:Contenuto del floppy diskContenuto del floppy disk Il floppy disk allegato costituisce una raccolta di Problemi di cooperazione nel modello a scambio di messaggiProblemi di cooperazione nel modello a scambio di messaggi VIII) Scrivere Problemi di cooperazione nel modello a scambio di messaggiProblemi di cooperazione nel modello a scambio di messaggi VII) Scrivere |
Impiego del costrutto monitor
XI) Si implementi il problema dei produttori/consumatori utilizzando il costrutto monitor.
Descrizione: Il costrutto monitor rappresenta un meccanismo di alto livello per implementare una risorsa gestore. In generale occorre definire, oltre alla risorsa da gestire, una struttura dati supplementare che contenga informazioni sullo stato della risorsa gestita. Una o più variabili di tipo condition vengono poi utilizzate per bloccare o sbloccare selettivamente i processi che competono per il controllo della risorsa, ciascuno in funzione della verifica (o meno) di una opportuna condizione di sincronizzazione. Il programma seguente implementa il problema dei produttori/consumatori:
Un produttore che voglia scrivere un contenuto nel buffer di memoria condivisa deve farlo in mutua esclusione con gli altri produttori.
Un consumatore che voglia prelevare un contenuto dal buffer di memoria condivisa deve farlo in mutua esclusione con gli altri consumatori.
Quando un produttore riesce ad ottenere l'accesso al buffer, dopo avervi depositato un contenuto, sblocca uno dei consumatori eventualmente in attesa.
Quando un consumatore riesce ad ottenere l'accesso al buffer, una volta prelevatone il contenuto, sblocca uno dei produttori eventualmente in attesa.
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 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
Monitor.H (L'implementazione è quella indicata per il programma IX)
#include <stdio.h>
#include <sys/wait.h>
#include "semafori.h"
typedef struct Monitor;
//Definizione di MACRO per l'accesso ai semafori del Monitor
#define MUTEX 0 //Il primo semaforo è sempre il Mutex
#define INITIALIZE(M,S,V) Init_Sem(M->ID_Sem,S,V)
#define WAIT(M,S) Wait_Sem(M->ID_Sem,S)
#define SIGNAL(M,S) Signal_Sem(M->ID_Sem,S)
#define AWAITING(M,S) Awaiting_Sem(M->ID_Sem,S)
#define ENTER_MONITOR(M) WAIT(M,MUTEX) //Implementazione della Entry
#define LEAVE_MONITOR(M) SIGNAL(M,MUTEX)
void Create_Monitor(Monitor*, int); //Semaforo Mutex e variabili Conditions vengono allocati
void Destroy_Monitor(Monitor*); //Semaforo Mutex e variabili Conditions vengono deallocati
void Wait_Cond(Monitor*, int); //Emula la Wait su una variabile Condition
void Signal_Cond(Monitor*, int); //Emula la Signal su una variabile Condition
Prod_Cons_Monitor.H
#include "monitor.h"
#define DIM_QUEUE 4 //Cardinalità del Buffer (Coda circolare)
#define VUOTO 0 //Stati del singolo buffer della Coda circolare
#define IN_USO 1
#define PIENO 2
typedef struct Buffer;
void Init_Buffer(Buffer*); //Inizializza il Buffer
void Start_Monitor(Monitor*); //Inizializza il Monitor
void Stop_Monitor(Monitor*); //Elimina il Monitor
int Inizio_Consumo(Monitor*, Buffer*); //Acquisizione di un buffer per consumo
char Consumo(int, Buffer*); //Consumo di un buffer
void Fine_Consumo(int, Monitor*, Buffer*); //Rilascio del buffer dopo un consumo
int Inizio_Produzione(Monitor*, Buffer*); //Acquisizione del buffer per la produzione
void Produzione(int, char, Buffer*); //Produzione di un buffer
void Fine_Produzione(int, Monitor*, Buffer*); //Rilascio del buffer dopo la produzione
Prod_Cons_Monitor.C
#include "lett_scritt_monitor.h"
#define SOSPESI_CONSUMATORI 1
#define SOSPESI_PRODUTTORI 2
void Init_Buffer(Buffer* B)
void Start_Monitor(Monitor* M)
void Stop_Monitor(Monitor* M)
int Inizio_Consumo(Monitor* M, Buffer* B)
if (i==B->testa) B->testa=(B->testa+1) % DIM_QUEUE;
B->stato[i]=IN_USO;
LEAVE_MONITOR(M);
return i;
char Consumo(int i, Buffer* B)
void Fine_Consumo(int i, Monitor* M, Buffer* B)
int Inizio_Produzione(Monitor* M, Buffer* B) while (B->stato[B->coda]!=VUOTO);
B->stato[i]=IN_USO;
LEAVE_MONITOR(M);
return i;
void Produzione(int i, char value, Buffer* B)
void Fine_Produzione(int i, Monitor* M, Buffer* B)
Programma XI.C
#include 'prod_cons_monitor.h'
#define DIM sizeof(Buffer) //Dimensione dell'area di memoria condivisa
#define NUM_PROD 3 //Numero di processi produttori
#define NUM_PRODUZ 5 //Numero di produzioni per ogni processo produttore
#define NUM_CONS 5 //Numero di processi consumatori
#define NUM_CONSUM 3 //Numero di consumi per ogni processo consumatore
void main()
Ptr_Buf=(Buffer*)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==(Buffer*)-1)
Init_Buffer(Ptr_Buf); //Inizializzazione del Buffer
//----- CREAZIONE DEL MONITOR -----
Monitor M;
Start_Monitor(&M);
//----- GENERAZIONE FIGLI PRODUTTORI -----
for(i=0; i<NUM_PROD; i++) else if (!pid)
exit(0); //Il figlio Produttore termina correttamente
}
} //End For NUM_PROD
//----- GENERAZIONE FIGLI CONSUMATORI -----
for(i=0; i<NUM_CONS; i++) else if (!pid)
exit(0); //Il figlio Consumatore termina correttamente
}
} //End For NUM_CONS
//----- SINCRONIZZAZIONE DEL PADRE CON I FIGLI -----
for(i=0; i<NUM_PROD+NUM_CONS; i++)
//----- DISTRUZIONE DEL MONITOR -----
Stop_Monitor(&M);
//----- RILASCIO BUFFER DI MEMORIA CONDIVISA -----
shmctl(ID_Buf, IPC_RMID, 0);
Appunti su: |
|