Faranno eseguiti simultaneamente, ma in realtà non in parallelamente. Il sistema operativo passa frequentemente avanti e indietro tra i due thread, in modo che entrambi siano in grado di svolgere il proprio lavoro. Questo è ciò che si intende per "concurrent"; un thread non deve attendere che l'altro termini prima che possa iniziare a funzionare. Ma a causa del GIL, non funzioneranno mai entrambi nello stesso momento, in cui ognuno viene eseguito su un core diverso in parallelo. Ogni thread verrà eseguito per un po ', interromperà mentre l'altro thread viene eseguito, quindi ricomincerà a funzionare, quindi metterà in pausa, ecc.
Questo è abbastanza facile da vedere se si esegue solo il codice di esempio. Ecco l'output sulla mia macchina:
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
Chiaramente, entrambi i thread sono in esecuzione. Ogni thread è solo in esecuzione più lentamente di quanto sarebbe se un thread fosse in esecuzione nel programma.
Considerate questo esempio, in cui ogni filo calcola la sequenza Fibonacci:
import thread
import time
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
def test():
while True:
start = time.time()
out = fib(32)
print "hello %s: %s" % (out, str(time.time() - start))
def test2():
while True:
out = fib(20)
def start_thread():
try:
thread.start_new_thread(test2,())
except:
print "Error: Unable to start thread"
#start_thread()
test()
Con solo test
esecuzione (quindi senza seconda filettatura), ottengo questo output:
hello 2178309: 0.953778982162
hello 2178309: 0.954975128174
hello 2178309: 0.95578789711
hello 2178309: 0.949182033539
Se inizio fino test2
in background, così, ottengo questo:
hello 2178309: 4.07990288734
hello 2178309: 4.08523893356
hello 2178309: 2.51651597023
hello 2178309: 2.13291287422
hello 2178309: 2.19885015488
Come puoi vedere, le prestazioni hanno un enorme successo.
Nota che se uno dei thread sta facendo qualcosa che rilascia l'I/O di blocco simile a GIL, o chiama in una libreria C che rilascia GIL, non vedrai questo tipo di degrado delle prestazioni, perché in quello caso entrambi i thread possono effettivamente funzionare in parallelo. Questo non si applica nell'esempio precedente, poiché nessuno dei due thread sta eseguendo lavori che rilasciano GIL.
Non stai chiamando start_thread da nessuna parte? – ZdaR
Questo codice era solo a scopo illustrativo lol Spiacente, ho appena aggiunto la riga di codice che avvia il thread –