Sulla base di questo question ho ipotizzato che la creazione di nuovo processo dovrebbe essere quasi veloce come la creazione dinuovo thread in Linux. Tuttavia, un piccolo test ha mostrato risultati molto diversi. Ecco il mio codice:Python vs. threading multiprocessing in Linux
from multiprocessing import Process, Pool
from threading import Thread
times = 1000
def inc(a):
b = 1
return a + b
def processes():
for i in xrange(times):
p = Process(target=inc, args=(i,))
p.start()
p.join()
def threads():
for i in xrange(times):
t = Thread(target=inc, args=(i,))
t.start()
t.join()
Test:
>>> timeit processes()
1 loops, best of 3: 3.8 s per loop
>>> timeit threads()
10 loops, best of 3: 98.6 ms per loop
Così, i processi sono quasi 40 volte più lento per creare! Perché succede? E 'specifico per Python o queste librerie? O ho semplicemente interpretato male la risposta sopra?
UPD 1. Per renderlo più chiaro. Comprendo che questa parte di codice non introduce alcuna concorrenza. L'obiettivo qui è di testare il tempo necessario per creare un processo e un thread. Per utilizzare vera e propria concorrenza con Python si può usare qualcosa di simile a questo:
def pools():
pool = Pool(10)
pool.map(inc, xrange(times))
che corre in realtà molto più veloce rispetto alla versione filettata.
UPD 2. Ho aggiunto la versione con os.fork()
:
for i in xrange(times):
child_pid = os.fork()
if child_pid:
os.waitpid(child_pid, 0)
else:
exit(-1)
I risultati sono:
$ time python test_fork.py
real 0m3.919s
user 0m0.040s
sys 0m0.208s
$ time python test_multiprocessing.py
real 0m1.088s
user 0m0.128s
sys 0m0.292s
$ time python test_threadings.py
real 0m0.134s
user 0m0.112s
sys 0m0.048s
Bene, la domanda a cui si è collegati sta confrontando il costo della semplice chiamata di 'fork (2)' contro 'pthread_create (3)', mentre il codice fa un po 'di più. Che ne dici di confrontare 'os.fork()' con 'thread.start_new_thread()'? – Aya
@Aya: Non sono riuscito a trovare alcun tipo di 'join' nel modulo' thread' per creare test simili, ma anche rispetto alla versione 'threading' di alto livello con' os.fork() 'è ancora molto più lento. In realtà, è il più lento (anche se condizioni aggiuntive possono influire sulle prestazioni). Vedi il mio aggiornamento. – ffriend
Devi usare un mutex per aspettare il thread se stai usando il modulo 'thread' di basso livello, che è come il modulo' threading' di livello superiore implementa 'join()'. Ma, se stai solo provando a misurare il tempo necessario per creare il nuovo processo/thread, non dovresti chiamare 'join()'. Vedi anche la mia risposta qui sotto. – Aya