2012-03-25 18 views
4

EDIT: Ich habe dies in Python als Fehler bestätigt. Es ist der Bug http://bugs.python.org/issue10332 (Ich habe einen neuen Fehler eingereicht, woraufhin mich der Betreuer auf 10332 verwiesen hat). Ich habe das Multiprocessing-Verzeichnis aus Python-Quell-Repository in mein Projektverzeichnis kopiert, und der Testfall funktioniert nun ordnungsgemäß.python multiprocessing mit maxtasksperchild

Dieses scheinbar einfache Programm funktioniert nicht für mich, wenn ich den Parameter maxtasksperchild nicht entferne. Was mache ich falsch?

from multiprocessing import Pool 
import os 
import sys 

def f(x): 
    print "pid: ", os.getpid(), " got: ", x 
    sys.stdout.flush() 
    return [x, x+1] 

def cb(r): 
    print "got result: ", r 

if __name__ == '__main__': 
    pool = Pool(processes=1, maxtasksperchild=9) 
    keys = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    result = pool.map_async(f, keys, chunksize=1, callback=cb) 
    pool.close() 
    pool.join() 

Wenn ich es laufen, erhalte ich:

$ python doit.py 
pid: 6409 got: 1 
pid: 6409 got: 2 
pid: 6409 got: 3 
pid: 6409 got: 4 
pid: 6409 got: 5 
pid: 6409 got: 6 
pid: 6409 got: 7 
pid: 6409 got: 8 
pid: 6409 got: 9 

Und es hängt. Das heißt, der neue Arbeiter, der das 10. Element verarbeiten soll, wurde nicht erzeugt.

In einem anderen Terminal, ich sehe:

$ ps -C python 
    PID TTY   TIME CMD 
6408 pts/11 00:00:00 python 
6409 pts/11 00:00:00 python <defunct> 

Das auf Ubuntu erfolgt 11.10 Python läuft 2.7.2+ (von Ubuntu-Pakete installiert).

+0

Ich denke, das ist ein Fehler in Python. Mein Aufruf von pool.close() (was die Dokumente sagen, dass ich vor dem Aufruf von pool.join() aufrufen sollte) setzt das Flag pool._state auf CLOSE. Die Funktion Pool._handle_workers beruht darauf, dass dieses Flag "RUN" ist, um neue Worker-Prozesse zu starten. Eine Problemumgehung für den Fehler besteht darin, nach dem Aufruf von map_async für etwa 10 Sekunden zu schlafen, bis pool.close() aufgerufen wird. Ich werde wahrscheinlich einen Fehler gegen Python einreichen. – user188012

+0

Ich kann diesen Wert bestätigen. Python 2.7.2 hatte dasselbe Problem mit maxtasksperchild = 1. Das Script wurde am Poolpool.join() gehängt, nachdem alle Aufgaben erfolgreich ausgeführt wurden und alle untergeordneten Prozesse zombie belassen (). Wenn Sie diesen Parameter aus der Poolerstellung entfernen, wurde das Problem behoben. –

+0

wurde das jemals gelöst? – user3467349

Antwort

-2

ich nie Multithreading in Python verwendet, aber ich denke, man maxtasksperchild = 10 auf dieser Linie machen will: pool = Pool(processes=1, maxtasksperchild=9) und den Ausgang danach Änderung:

bedeutet
pid: 8436 got: 1 
pid: 8436 got: 2 
pid: 8436 got: 3 
pid: 8436 got: 4 
pid: 8436 got: 5 
pid: 8436 got: 6 
pid: 8436 got: 7 
pid: 8436 got: 8 
pid: 8436 got: 9 
pid: 8436 got: 10 
got result: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11]] 
+0

Gut zu hören, dass Sie auch die gleiche Ausgabe wie ich für 9 bekommen. Aber was Sie geschrieben haben, beantwortet meine Frage nicht. maxtasksperchild = 10 funktioniert, weil kein Respawn des Arbeitsprozesses erforderlich ist. Warum funktioniert maxtasksperchild = 9 nicht? – user188012

0

maxtasksperchild eine Verarbeitung maximale Anzahl von Aufgaben ausführen

0

Dieses Problem wurde in Python3 behoben.

pid: 18316 got: 1 
pid: 18316 got: 2 
pid: 18316 got: 3 
pid: 18316 got: 4 
pid: 18316 got: 5 
pid: 18316 got: 6 
pid: 18316 got: 7 
pid: 18316 got: 8 
pid: 18316 got: 9 
pid: 18317 got: 10 
got result: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11]]