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).
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
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. –
wurde das jemals gelöst? – user3467349