El script que usa el módulo de multiprocesamiento no termina

El siguiente código, no se imprime "here" . ¿Cuál es el problema? Lo probé en mis dos máquinas (windows 7, Ubuntu 12.10) y http://www.compileonline.com/execute_python_online.php No se imprime "here" en todos los casos.

 from multiprocessing import Queue, Process def runLang(que): print "start" myDict=dict() for i in xrange(10000): myDict[i]=i que.put(myDict) print "finish" def run(fileToAnalyze): que=Queue() processList=[] dicList=[] langs= ["chi","eng"] for lang in langs: p=Process(target=runLang,args=(que,)) processList.append(p) p.start() for p1 in processList: p1.join() print "here" for _ in xrange(len(langs)): item=que.get() print item dicList.append(item) if __name__=="__main__": processList = [] for fileToAnalyse in ["abc.txt","def.txt"]: p=Process(target=run,args=(fileToAnalyse,)) processList.append(p) p.start() for p1 in processList: p1.join() 

Esto se debe a que cuando se put muchos elementos en un multiprocessing.Queue . Una vez que el Pipe subyacente está lleno, finalmente se almacenan en búfer en la memoria. El búfer no se vaciará hasta que algo comience a leer desde el otro extremo de la Queue , lo que permitirá que Pipe acepte más datos. Un Process no puede terminar hasta que el búfer para todas sus instancias de Queue se haya vaciado por completo en su Pipe subyacente. La implicación de esto es que si intenta join un proceso sin que otro proceso / subproceso de llamada se get en su Queue , podría interrumpirse. Esto se menciona en los documentos :

Advertencia

Como se mencionó anteriormente, si un proceso hijo ha puesto elementos en una cola (y no ha usado JoinableQueue.cancel_join_thread ), ese proceso no terminará hasta que todos los elementos almacenados se hayan descargado al canal.

Esto significa que si intenta unirse a ese proceso puede obtener un interlocking a menos que esté seguro de que todos los elementos que se han puesto en la cola se han consumido. De manera similar, si el proceso hijo no es demoníaco, el proceso padre puede colgarse en la salida cuando intenta unirse a todos sus hijos no demoníacos.

Tenga en cuenta que una cola creada con un administrador no tiene este problema.

Puede solucionar el problema al no llamar a join hasta que después de vaciar la Queue en el padre:

 for _ in xrange(len(langs)): item = que.get() print(item) dicList.append(item) # join after emptying the queue. for p in processList: p.join() print("here")