Python threading vs. multiprocessing im Linux

Basierend auf dieser Frage ich davon ausgegangen, dass die Schaffung neuen Prozess sollte fast so schnell wie erstellen neuen thread in Linux. Allerdings, kleiner test zeigte ganz anderes Ergebnis. Hier ist mein code:

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()

Tests:

>>> timeit processes() 
1 loops, best of 3: 3.8 s per loop

>>> timeit threads() 
10 loops, best of 3: 98.6 ms per loop

So, die Prozesse sind fast 40 mal langsamer zu erstellen! Warum ist es passiert? Ist es spezifisch für Python oder diese Bibliotheken? Oder habe ich es nur falsch interpretiert die Antwort oben?


UPD 1. Zu machen, mehr klar. Ich verstehe, dass dieses Stück code nicht wirklich vorstellen jede Parallelität. Das Ziel hier ist das testen die Zeit, die benötigt wird, um einem Prozess und einem thread. Der Einsatz von real-Parallelität mit Python kann man so etwas wie dieses:

def pools():
    pool = Pool(10)
    pool.map(inc, xrange(times))

denen läuft wirklich viel schneller, als Gewinde-version.


UPD 2. Ich habe die version mit os.fork():

for i in xrange(times):
    child_pid = os.fork()
    if child_pid:
        os.waitpid(child_pid, 0)
    else:
        exit(-1)

Ergebnisse:

$ 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
  • Gut, die Frage, die Sie verknüpft, ist der Vergleich der Kosten von nur aufrufen fork(2) vs. pthread_create(3), während Ihr code wird schon ein bisschen mehr. Wie über den Vergleich von os.fork() mit thread.start_new_thread()?
  • Ich konnte Sie nicht finden jede Art von join im thread Modul zu erstellen, ähnlich wie Prüfungen, aber auch im Vergleich zu high-level - threading version mit os.fork() ist noch viel langsamer. In der Tat, es ist das langsamste ist (wenn zusätzliche Bedingungen können die Leistung beeinflussen). Siehe mein update.
  • Sie einen mutex verwenden müssen, zu warten, bis der thread, wenn Sie mit der low-level - thread - Modul, welches, wie die höheren-Ebene threading Modul implementiert join(). Aber, wenn Sie nur versuchen die Zeit Messen, die es braucht, um erstellen Sie die neue Prozess/thread, dann sollten Sie nicht fordern join(). Siehe auch meine Antwort unten.
InformationsquelleAutor ffriend | 2013-07-02
Schreibe einen Kommentar