====== Esercitazione 7 ====== ===== Esercizio 1 ===== Realizzare una shell **rudimentale** che legge un comando con eventuali parametri dallo standard input e ne invoca l'esecuzione utilizzando una funzione della famiglia ''exec()''. La shell deve terminare se viene digitato il comando 'exit'. Il formato dei comandi accettati dalla shell è molto semplice e non non prevede metacaratteri, redirezione, pipe, etc... ===== Esercizio 1bis ===== Completare il codice seguente in modo che il programma calcoli i primi 13 numeri di Fibonacci utilizzando per ogni chiamata ''doFib'' un processo distinto. #include #include #include #include /* * Calcola ricorsivamente il numero di Fibonacci dell'argomento 'n'. * La soluzione deve forkare un nuovo processo che esegue una sola * chiamata di 'doFib'. * Se doPrint e' 1 allora la funzione lo stampa, altrimenti il * numero calcolato va passato al processo padre. */ static void doFib(int n, int doPrint); int main(int argc, char *argv[]) { // questo programma puo' calcolare i numeri di Fibonacci solo fino a 13. const int NMAX=13; int arg; if(argc != 2){ fprintf(stderr, "Usage: %s \n", argv[0]); return EXIT_FAILURE; } arg = atoi(argv[1]); if(arg < 0 || arg > NMAX){ fprintf(stderr, "num deve essere compreso tra 0 e 13\n"); return EXIT_FAILURE; } doFib(arg, 1); return 0; } ===== Esercizio 2 ===== Scrivere un programma C con due threads, un produttore (P) ed un consumatore (C). Il thread P genera, uno alla volta, una sequenza di numeri inserendoli in un buffer di una sola posizione condiviso con il thread C. Il thread consumatore estrae i numeri dal buffer e li stampa sullo standard output. Se il buffer e' pieno P attende che C consumi il dato, analogamente se il buffer e' vuoto C attende che P produca un valore da consumare. ===== Esercizio 3 ==== Scrivere un programma C che implementa una //pipeline// di tre threads. Il primo thread legge una riga alla volta da un file testuale (il cui nome e' passato come argomento al programma) ed invia al secondo threads ogni riga letta dal file. Il secondo threads "tokenizza" le parole dalla riga ricevuta dal primo thread ed invia al terzo thread i token. Il terzo thread contralla quali parole sono uniche e alla fine, prima di terminare, stampa tutte le parole uniche individuate (cioe' stampa tulle le parole del file in input che compaiono una sola volta al suo interno). I tre stadi del pipeline devono lavorare in modo concorrente come in una "catena di montaggio", il buffer di comunicazione tra due stadi della pipeline deve essere implementata con una coda FIFO. ===== Homework ===== N filosofi siedono ad una tavola con un piatto di spaghetti davanti ed una forchetta alla loro destra ed una alla loro sinistra. Per mangiare gli spaghetti un filosofo ha bisogno di entrambe le forchette vicine. Ogni filosofo è impegnato ininterrottamente in una sequenza di 3 attivita': meditare, cercare di acquisire le forchette e mangiare. Scrivere un programma C che attivi N thread filosofi che eseguono il ciclo descritto per 100 volte. La meditazione e la fase in cui il filosofo mangia deve essere implementata con un ritardo variabile (usare ad esempio la chiamata di sistema ''nanosleep'' e la funzione ''rand_r()'').