Prima di tutto, rimuovere la riga print '******...'
. Semplicemente confonde tutti. Invece, proviamo questo codice ...
import os
import time
for i in range(2):
print "I'm about to be a dad!"
time.sleep(5)
pid = os.fork()
if pid == 0:
print "I'm {}, a newborn that knows to write to the terminal!".format(os.getpid())
else:
print "I'm the dad of {}, and he knows to use the terminal!".format(pid)
os.waitpid(pid)
Ok, prima di tutto, cos'è la "forcella"? La forcella è una caratteristica dei sistemi operativi moderni e conformi agli standard (ad eccezione di M $ Windows: la battuta di un sistema operativo è tutt'altro che moderna e conforme agli standard) che consente un processo (noto come "programma" e che include il Interprete Python!) Per fare letteralmente un duplicato esatto di se stesso, creando effettivamente un nuovo processo (un'altra istanza del "programma"). Una volta che la magia è terminata, entrambi i processi sono indipendenti. Cambiare qualcosa in uno di essi non ha effetto sull'altro.
Il processo responsabile della spiegazione di questo incanto oscuro e antico è noto come processo genitore. Il risultato senz'anima di questa abominazione nella vita stessa è noto come processo del bambino.
Come dovrebbe essere ovvio a tutti, compresi quelli per i quali non lo è, puoi diventare un membro di quel gruppo selezionato di programmatori che hanno venduto la loro anima per mezzo di os.fork()
. Questa funzione esegue un'operazione a forcella e, di conseguenza, genera un secondo processo creato dal nulla.
Ora, cosa restituisce questa funzione o, ancora più importante, come restituisce? Se non vuoi diventare pazzo, per favore, non andare a leggere il file /kernel/fork.c
del kernel Linux!Una volta che il kernel fa ciò che sappiamo deve fare, ma non vogliamo accettarlo, os.fork()
restituisce in i due processi! Sì, anche lo stack di chiamate è copiato!
Quindi, se sono copie esatte, come fa una differenza tra genitore e figlio? Semplice. Se il risultato di os.fork()
è zero, allora stai lavorando nel figlio. Altrimenti, stai lavorando in parent e il valore di ritorno è il PID (Process IDentifier) del bambino. Ad ogni modo, il bambino può ottenere il proprio PID da os.getpid()
, no?
Ora, tenendo conto di questo, e il fatto che fare fork()
all'interno di un ciclo è la ricetta per il disordine, questo è ciò che accade. Chiamiamo il processo originale il processo "master" ...
- Master:
i = 0
, forchette in bambino- # 1-di-master
- Child # 1-di-master:
i = 1
forchette in bambino- # 1-del-bambino- # 1-di-master
- Child # 1-del-bambino- # 1-di-master:
for
ciclo su, esce
- Child # 1-di-master :
for
loop over, uscite
- Master:
i = 1
, forchette in bambino- # 2-di-master
- Child # 2-di-master:
i = 1
forchette in bambino- # 1-del-bambino- # 2-di-master
- Child # 1-del-bambino- # 2-di-master:
for
ciclo su, esce
- Child # 2-di-master:
for
ciclo su, esce
- master:
for
ciclo su , uscite
Come si può vedere, ci sono un totale di 6 processi, con conseguente 6 linee di produzione, una cosa del genere ...
Sono il papà di 12120, e sa utilizzare il terminale!
Sono 12120, un neonato che sa scrivere sul terminale!
Sono il papà del 12121 e sa usare il terminale!
Sono 12121, un neonato che sa scrivere sul terminale!
Sono il papà del 12122 e sa usare il terminale!
Sono 12122, un neonato che sa scrivere sul terminale!
Ma questo è solo arbitrario, potrebbe avere in uscita questo fuori invece ...
Sono 12120, un neonato che sa scrivere sul terminale!
Sono il papà di 12120 e sa usare il terminale!
Sono 12121, un neonato che sa scrivere sul terminale!
Sono il papà del 12121 e sa usare il terminale!
Sono 12122, un neonato che sa scrivere sul terminale!
Sono il papà del 12122 e sa usare il terminale!
O altro. Il sistema operativo (e gli orologi funky della scheda madre) è l'unico responsabile dell'ordine in cui i processi ottengono tempi, quindi vai blame on Torvalds (and expect no self-steem when back) se non ti piace come il kernel gestisce l'organizzazione dei tuoi processi;).
Spero che questo abbia portato un po 'di luce su di te!
hai ragione. e dovrei chiamare os._exit() nel sottoprocesso per evitare la forchetta profonda ... – tudouya
@tudouya Giusto. O semplicemente rompere il ciclo. – glglgl