La chiamata wait() in Python

Abbiamo visto, nelle esercitazioni precedenti, il comportamento non deterministico delle chiamate fork con l’esecuzione di figli, anche simulando codice con la chiamata time.sleep(). Il comportamento in questi casi è lasciato allo scheduler ma in molti casi, è consigliabile che il padre attenda l’esecuzione dei figli, magari per raccogliere i dati elaborati e usarli nel flusso principale.

Ci occorre un meccanismo, il più possibile semplice, per forzare il padre a non terminare prima che i figli non abbiano completato la loro vita. E’ qui che ci aiuta la chiamata wait. La chiamata wait ritorna una tupla costituita dal id del processo ritornato e una cifra intera. In realtà se convertiamo il numero in binario di 16 cifre otteremo nei primi 8 bit a destra il valore di ritorno dell ostato del figlio, 0 se termina in modo normale, un numero maggiore se ci sono chiamate che uccidono o terminano il processo figlio (KILL, SIGTERM). Gli 8 bit più a sinistra se riconvertiti sono il valore che ritorniamo nella parentesi dell’exit  del processo figlio. Il valore passato alla funzione exit è un numero compreso tra o e 255 in genere. E’ arbitrario ma solitamente se pari a zero restituisce una uscita “positiva”, “1” se c’è stato qualcosa che non va. Con altri valori potrebbero essere tracciati altri errori su misura per il software che stiamo realizzando. Proviamo, come sempre, questi frammenti di codice su un IDE come PyCharm on online su un sito come Repl.it

'''
Abbiamo visto come le chiamate fork non siano deterministiche
ma risenton odell'esecuizione decisa dallo scheduler del OS
'''
import os
import sys

pid = os.fork()
if pid == 0:
  print ("Sono il figlio, il mio PID è: " + str(os.getpid()))
  print ("Mio padre è: "+ str(os.getppid()))
  os._exit(50)
else :
  print ("Sono il padre, il mio PID è: " + str(os.getpid()))
  '''
  il padre attende i figli
  '''
  status = os.wait() 

  '''
  ritorna un vettore col PID del figlio finito e un numero di 16bit
  col valore dello stato
  '''
  print ("L'exit del mio figlio è: " + str(status)) 

Un altro esempio con le stesse chiamate. Provate anche  a commentare/cancellare la _exit nel figlio. Cosa accade?

import os

#creiamo il solito figlio
pid = os.fork()

if pid is 0:
    # Al figlio faccio stampare dei numeri
    for i in range(0,10):
        print("Figlio stampa: "+ str(i))
    print("Il figlio " + str(os.getpid()) +" sta uscendo" )
    os._exit(0);
else:
    # il padre attende
    status = os.wait()
    print("Il mio figlio uscito è: "+ str(status[0]))
    print("Io sono il padre: " +  str(os.getpid()))

Ultima modifica 2 Maggio 2022