Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
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 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:
<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
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