Warning: Undefined array key "view" in /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php on line 2
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php on line 47
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php on line 48
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php on line 49
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php on line 50
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-examples/index.php on line 51
/**
* Due figli: un produttore ed un consumatori di numeri generati a
* random. I due processi usano una area di memoria condivisa che
* contiene piu' elementi e 3 semafori per coordinarsi.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DIM_BUFFER 10
#define HOW_MANY 200
#define S_MUTEX 0
#define S_EMPTY 1
#define S_FULL 2
int WAIT(int sem_des, int num_semaforo) {
struct sembuf operazioni[1] = {{num_semaforo, -1, 0}};
return semop(sem_des, operazioni, 1);
}
int SIGNAL(int sem_des, int num_semaforo) {
struct sembuf operazioni[1] = {{num_semaforo, +1, 0}};
return semop(sem_des, operazioni, 1);
}
// produce numeri random e li scrive nella memoria condivisa
void produttore(int shm, int sems) {
int *p, *in, *out;
int i, number, len;
long tot = 0;
srand(time(NULL)); // randomizza il generatore di numeri pseudo-causali
if ((p = (int *)shmat(shm, NULL, 0)) ==
(int *)-1) { // attacca la memoria condivisia
perror("shmat");
exit(1);
}
in = p + DIM_BUFFER; // la penultima posizione conterra' l'indice
// dell'inizio coda
out = p + DIM_BUFFER +
1; // l'ultima posizione conterra' l'indice della fine della coda
*in = 0;
*out = 0;
for (i = 0; i < HOW_MANY; i++) {
number = rand() % 500;
WAIT(sems, S_EMPTY); // diminuisce le posizioni vuote
WAIT(sems, S_MUTEX); // entra nella sezione critica
p[*in] = number; // scrive il numero nella coda
*in =
(*in + 1) % DIM_BUFFER; // sposta l'indice in avanti (ciclicamente)
len = (*in > *out ? (*in - *out)
: (DIM_BUFFER -
(*out - *in))); // calcola in # di elementi in coda
printf("Produttore: %d \t(in=%d out=%d len=%d)\n", number, *in, *out,
len);
tot += number;
SIGNAL(sems, S_MUTEX); // esce dalla sezione critica
SIGNAL(sems, S_FULL); // incrementa le posizioni piene
usleep(rand() % 40000);
}
printf("Produttore: totale finale=%ld\n", tot);
exit(0);
}
// legge i numeri dalla coda e li stampa a video
void consumatore(int shm, int sems) {
int *p, *in, *out;
int i, number, len;
long tot = 0;
if ((p = (int *)shmat(shm, NULL, 0)) ==
(int *)-1) { // attacca la memoria condivisia
perror("shmat");
exit(1);
}
in = p + DIM_BUFFER; // la penultima posizione conterra' l'indice
// dell'inizio coda
out = p + DIM_BUFFER +
1; // l'ultima posizione conterra' l'indice della fine della coda
for (i = 0; i < HOW_MANY; i++) {
WAIT(sems, S_FULL); // diminuisce le posizioni piene
WAIT(sems, S_MUTEX); // entra nella sezione critica
number = p[*out]; // legge il numero dalla coda
*out =
(*out + 1) % DIM_BUFFER; // sposta l'indice in avanti (ciclicamente)
len =
(*in >= *out ? (*in - *out)
: (DIM_BUFFER -
(*out - *in))); // calcola in # di elementi in coda
printf("Consumatore: %d \t(in=%d out=%d len=%d)\n", number, *in, *out,
len);
tot += number;
SIGNAL(sems, S_MUTEX); // esce dalla sezione critica
SIGNAL(sems, S_EMPTY); // incrementa le posizioni vuote
usleep(rand() % 40000);
}
printf("Consumatore: totale finale=%ld\n", tot);
exit(0);
}
int main() {
int id_shm, id_sems;
// crea l'area di memoria condivisa per i DIM_BUFFER numeri e due variabili
// aggiuntive
if ((id_shm = shmget(IPC_PRIVATE, (DIM_BUFFER + 2) * sizeof(int),
IPC_CREAT | 0600)) == -1) {
perror("shmget");
exit(1);
}
// crea i 3 semafori (S_MUTEX, S_EMPTY, S_FULL)
if ((id_sems = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)) == -1) {
perror("semget");
exit(1);
}
// imposta i valori iniziali dei semafori
semctl(id_sems, S_MUTEX, SETVAL, 1);
semctl(id_sems, S_EMPTY, SETVAL, DIM_BUFFER);
semctl(id_sems, S_FULL, SETVAL, 0);
// semctl(id_sems, 0, SETALL, {1, DIM_BUFFER, 0});
// crea i due processi figli: produttore e consumatore
if (fork() != 0) {
if (fork() != 0) {
// corpo del padre
wait(NULL);
wait(NULL);
} else {
produttore(id_shm, id_sems);
}
} else {
consumatore(id_shm, id_sems);
}
// distrugge memoria condivisa e semaforo
shmctl(id_shm, IPC_RMID, NULL);
semctl(id_sems, 0, IPC_RMID, 0);
exit(0);
}