|
Appunti informatica |
|
Visite: 1289 | Gradito: | [ Picolo appunti ] |
Leggi anche appunti:L'accessibilitÀ e la durata delle variabiliL'accessibilità e la durata delle variabili In C le variabili possono essere I device driverI device driver Sempre più difficile: dopo avere affrontato i TSR (pag. 169) Gli operatoriGli operatori Come tutti i linguaggi di programmazione, il C dispone di un insieme |
Problemi di cooperazione nel modello a memoria comune
III) Scrivere un'applicazione concorrente che implementi il problema 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:
il consumo di un singolo buffer di memoria comune (l'insieme del pool è allocato dal processo padre) da parte di un processo consumatore non può avvenire se non dopo che almeno un processo produttore vi abbia depositato un contenuto, e all'atto del consumo tale contenuto viene cancellato.
un processo produttore non può depositare in un buffer di memoria comune un nuovo contenuto se non è disponibile alcun buffer libero.
A garanzia della consistenza del contenuto del buffer condiviso, processi consumatori e processi 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.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
Prod_Cons_Queue.H
#include <stdio.h>
#include "semafori.h"
#define DIM_QUEUE 4 //Cardinalità della Coda circolare
#define VUOTO 0 //Stati del singolo buffer della Coda circolare
#define IN_USO 1
#define PIENO 2
typedef struct Queue;
void Init_Queue(Queue*); //Inizializza la Coda circolare
void Init_Semafori_Queue(int); //Inizializza i semafori
int Richiesta_Produzione_Queue(Queue*, int); //Richiesta di un buffer libero per la produzione
void Produzione_Queue(int, char, Queue*); //Produzione di un carattere nella Coda circolare
void Rilascio_Produzione_Queue(int, Queue*, int); //Rilascio di un buffer pieno
int Richiesta_Consumo_Queue(Queue*, int); //Richiesta di un buffer pieno per il consumo
char Consumo_Queue(int, Queue*); //Consumo di un carattere dalla Coda circolare
void 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)
void Init_Semafori_Queue(int ID_Sem)
int Richiesta_Produzione_Queue(Queue* Q, int ID_Sem) while (Q->stato[Q->coda]!=VUOTO);
Q->stato[i]=IN_USO;
SIGNAL(MUTEX_PROD);
printf('Buffer %d in uson', i);
return i;
void Produzione_Queue(int i, char value, Queue* Q)
void Rilascio_Produzione_Queue(int i, Queue* Q, int ID_Sem)
int Richiesta_Consumo_Queue(Queue* Q, int ID_Sem)
if (i==Q->testa) Q->testa=(Q->testa+1) % DIM_QUEUE;
Q->stato[i]=IN_USO;
SIGNAL(MUTEX_CONS);
printf('Buffer %d in uson', i);
return i;
char Consumo_Queue(int i, Queue* Q)
void Rilascio_Consumo_Queue(int i, Queue* Q, int ID_Sem)
Programma III.C
#include <stdio.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include 'prod_cons_queue.h'
#define DIM sizeof(Queue) //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=(Queue*)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==(Queue*)-1)
Init_Queue(Ptr_Buf); //Inizializzazione della Queue
//----- CREAZIONE SEMAFORI -----
key_t Key_Sem=IPC_PRIVATE; //Chiave del semaforo/i
int ID_Sem; //Identificatore del semaforo/i
ID_Sem=semget(Key_Sem, 4, IPC_CREAT|0664); //Viene allocato un gruppo di semafori di cardinalità 4,
//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)
Init_Semafori_Queue(ID_Sem); //Inizializzazione dei semafori
//----- 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++)
//----- RILASCIO MEMORIA CONDIVISA E SEMAFORO -----
shmctl(ID_Buf, IPC_RMID, 0);
semctl(ID_Sem, 0, IPC_RMID);
Appunti su: |
|