#include #include #include #include #include #include #include #include #include #include #include #include #include /* ***esercizio B5 'fork di 20 processi' *** Ogni processo può fare il fork di al più altri 2 processi Avviare un totale di 20 processi, usando un contatore condiviso tra i processi Usare un semaforo per regolare l'accesso concorrente al contatore da parte dei processi (il contatore ha valore iniziale 0) processo iniziale incrementa crea due processi P1 e P2; P1 crea due processi P3 e P4; P2 crea due processi P5 e P6; P3 crea due process.... (prima di ogni singolo fork(), viene controllato il valore del contatore (deve essere < 20) ed incrementato il contatore condiviso) */ char * semaphore_name = "/es_bo5"; sem_t * sem; // verrà usato come mutex int * counter; // contatore condiviso tra processi int main() { sem_unlink(semaphore_name); sem = sem_open(semaphore_name, O_CREAT, S_IRUSR | S_IWUSR, 1); counter = mmap(NULL, sizeof(int), PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1 , 0); if (counter == MAP_FAILED) { perror("mmap"); exit(1); } *counter = 1; // contiamo il processo iniziale int fork_counter = 0; while (1) { pid_t pid = -1; printf("before sem_wait pid=%d\n", getpid()); if (sem_wait(sem) == -1) { // il processo acquisice il mutex perror("sem_wait"); exit(1); } // un processo alla volta passa di qua if (*counter < 20) { (*counter)++; printf("before fork pid=%d, counter = %d\n", getpid(), (*counter)); fork_counter++; pid = fork(); // dopo fork, il processo che ha acquisito il mutex passa di qua // ma anche il nuovo processo figlio passa di qua (ma non tocca il semaforo) if (pid == 0) { printf("just started new process pid=%d, ppid=%d\n", getpid(), getppid()); fork_counter = 0; } } if (pid != 0) { // il processo padre aveva acquisito il mutex, che ora rilasciamo printf("before sem_post pid=%d\n", getpid()); if (sem_post(sem) == -1) { perror("sem_post"); exit(1); } } if (*counter == 20 || fork_counter == 2) break; } int wait_counter = 0; while (wait(NULL) != -1) wait_counter++; printf("bye counter = %d, pid=%d, number of child processes: %d\n", *counter, getpid(), wait_counter); return 0; }