Warum kommuniziert Deadlock bei Verwendung mehrerer Popen-Subprozesse?

8

Das folgende Problem tritt nicht in Python 2.7.3 auf. Es tritt jedoch mit Python 2.7.1 und Python 2.6 auf meinem Computer (64-Bit Mac OSX 10.7.3) auf. Dies ist der Code, den ich irgendwann verteilen werde. Daher würde ich gerne wissen, ob es einen Weg gibt, diese Aufgabe abzuschließen, die nicht so dramatisch von der Python-Version abhängt.

Ich muss mehrere Unterprozesse parallel öffnen und STDIN-Daten zu jedem von ihnen schreiben. Normalerweise würde ich dies mit der Methode Popen.communicate machen. % Co_de% ist jedoch Deadlocking, wenn mehrere Prozesse gleichzeitig geöffnet sind.

%Vor%

Wenn ich die Anzahl der Prozesse in communicate ändere, ist die Ausgabe wie erwartet:

%Vor%

Wenn jedoch zwei Prozesse ( for _ in range(1) ) vorhanden sind, blockiert der Prozess unbegrenzt. Ich habe die Alternative versucht, manuell auf stdin zu schreiben:

%Vor%

Aber dann versucht jeder Versuch, von den Prozessen zu lesen, (zum Beispiel for _ in range(2) ) immer noch Deadlocks.

scheint zunächst verwandt zu sein, aber es gibt an, dass es auftritt, wenn mehrere Threads verwendet werden und dass das Deadlocking auftritt kommt nur sehr selten vor (während es hier immer vorkommt). Gibt es eine Möglichkeit, dies vor Version 2.7.3 mit Python-Versionen zu bewerkstelligen?

    
David Robinson 30.01.2013, 22:57
quelle

1 Antwort

9

Ich musste ein bisschen nach diesem suchen. (Ich bin einmal auf ein ähnliches Problem gestoßen, also dachte ich, ich wüsste die Antwort, aber ich habe mich geirrt.)

Das Problem (und Patch für 2.7.3) wird hier beschrieben:

Ссылка

Das Problem ist, dass die PIPEs von Unterprozessen geerbt werden. Die Antwort ist, 'close_fds = True' in Ihrem Popen-Aufruf zu verwenden.

%Vor%

Wenn das Probleme mit anderen Dateibeschreibungen verursacht, die Sie wollen (wenn es sich um ein vereinfachtes Beispiel handelt), stellt sich heraus, dass Sie mit den Unterprozessen in warten () / kommunizieren () können die umgekehrte Reihenfolge, in der sie erstellt wurden, und es scheint zu funktionieren.

dh statt:

%Vor%

verwenden:

%Vor%

(Oder, ich denke, mach 'processs.reverse ()' vor deiner bestehenden Schleife.)

    
John Hazen 31.01.2013, 01:32
quelle