.. role:: raw-html(raw) :format: html FEW - Fork-Exit-Wait ==================== .. code-block:: c :linenos: #include #include #include #include int main(){ int res, status; printf("I'm a process and I'm going to create a child\n"); res = fork(); if(res < 0) printf("I cannot create a child"); else if(res == 0){ sleep(5); printf("I'm the child!\n"); exit(1); } else{ printf("I'm now a parent and I'll wait for my child to die...\n"); wait(&status); printf("My child has invoked exit(%d)\n", WEXITSTATUS(status)); printf("My child is dead, so it's my time to die\n"); } exit(0); } Fork-Exit-Wait (:raw-html:`FEW `) è un semplice programma C per: 1. Creare un processo tramite :posix:`fork `. 2. Attendere la terminazione del processo appena creato tramite :posix:`wait `. 3. Terminare il processo corrente utilizzando :posix:`exit `. Il main thread esegue la stampa di riga 8 e successivamente invoca la :posix:`fork ` per creare un processo child. .. code-block:: c :lineno-start: 8 printf("I'm a process and I'm going to create a child\n"); res = fork(); Se la :posix:`fork ` fallisce (:code:`res == -1`), il processo principale termina. Altrimenti, entrambi i processi eseguono a partire dalla terminazione della :posix:`fork `. Per differenziare il flusso di esecuzione tra il processo parent ed il processo child occorre analizzare il risultato della :posix:`fork `. Il processo child legge :code:`res == 0`, mentre il processo parent :code:`res != 0` (più precisamente :code:`res` contiene il pid del processo child). A questo punto il child esegue: .. code-block:: c :lineno-start: 12 sleep(5); printf("I'm the child!\n"); exit(1); ossia va in stato di sleep per 5 secondi, esegue una stampa e termina con codice di terminazione 1 invocando la syscall :posix:`exit `. Il parent esegue: .. code-block:: c :lineno-start: 17 printf("I'm now a parent and I'll wait for my child to die...\n"); wait(&status); printf("My child has invoked exit(%d)\n", WEXITSTATUS(status)); printf("My child is dead, so it's my time to die\n"); Nello specifico attende la terminazione di uno generico thread child tramite la system call :posix:`wait `. Grazie a questa chiamata, può inoltre ottenere il codice di terminazione dalla variabile :code:`status` grazie alla macro :code:`WEXITSTATUS` (il codice è memorizzato nel secondo byte di :code:`status`). Riferimenti """"""""""" * [:ref:`t3 `] Sezione 1.2, 3.1 * :posix:`fork ` * :posix:`exit ` * :posix:`wait `