Warning: Undefined array key "view" in /var/www/html/wp-content/uploads/classes/so/1819/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/1819/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1819/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/1819/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1819/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/1819/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1819/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/1819/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1819/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/1819/lab-examples/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1819/lab-examples/index.php on line 51
/** * Variante con tre figli: un produttore ed due consumatori di numeri * generati a random. I tre 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 num, int howmany) { 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 < howmany; 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: %d \t(in=%d out=%d len=%d)\n", num, 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 %d: totale finale=%ld\n", num, tot); exit(0); } // legge i numeri dalla coda e li stampa a video void consumatore(int shm, int sems, int num, int howmany) { 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 < howmany; 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: %d \t(in=%d out=%d len=%d)\n", num, number, *in, *out, len); tot += number; SIGNAL(sems, S_MUTEX); // esce dalla sezione critica SIGNAL(sems, S_EMPTY); // incrementa le posizioni vuote usleep(rand() % 50000); } printf("Consumatore %d: totale finale=%ld\n", num, 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); // crea i due processi figli: produttore e consumatore if (fork() != 0) { if (fork() != 0) { if (fork() != 0) { // corpo del padre wait(NULL); wait(NULL); wait(NULL); } else { produttore(id_shm, id_sems, 1, HOW_MANY * 2); } } else { consumatore(id_shm, id_sems, 2, HOW_MANY); } } else { consumatore(id_shm, id_sems, 1, HOW_MANY); } // distrugge memoria condivisa e semaforo shmctl(id_shm, IPC_RMID, NULL); semctl(id_sems, 0, IPC_RMID, 0); exit(0); }