Warum blockiert multiprocessing.Lock () nicht freigegebene Ressourcen in Python?

9

Angenommen, ich habe eine sehr große Textdatei, die aus vielen Zeilen besteht, die ich gerne umkehren würde. Und mir ist die endgültige Bestellung egal. Die Eingabedatei enthält kyrillische Symbole. Ich verwende multiprocessing , um auf mehreren Kernen zu verarbeiten.

Ich schrieb ein solches Programm:

%Vor%

Dieses Programm schlägt mit Fehler fehl:

%Vor%

Auf der anderen Seite funktioniert alles gut, wenn ich POOL_NUMBER = 1 einstelle. Aber es macht keinen Sinn, wenn ich die Gesamtleistung erreichen möchte.

Warum passiert dieser Fehler? Und wie kann ich es beheben?

Ich benutze Python 3.5.2 .

Ich habe Daten mit diesem Skript generiert:

%Vor%     
Fomalhaut 01.11.2017, 13:36
quelle

2 Antworten

3

Das Problem hier ist das Lesen einer Datei aus mehreren Prozessen funktioniert nicht so, wie Sie denken, Sie können das open -Objekt nicht zwischen Prozessen teilen.

Sie könnten eine globale current_line Variable erstellen und jedes Mal die Datei lesen und die aktuelle Zeile verarbeiten, nicht ideal.

Hier ist ein anderer Ansatz, bei dem processes pool und map method verwendet werden, ich wiederhole die Datei und setze für jede Zeile die Zielmethode in die Warteschlange:

%Vor%

Mit 8 Prozess auf meiner Maschine: Total time 1.3367934226989746

Und mit 1 Prozess: Total time 4.324501991271973

Dies funktioniert am besten, wenn Ihre Zielfunktion CPU-gebunden ist. Ein anderer Ansatz bestünde darin, die Datei in POOL_NUMBER Chunks aufzuteilen und jeden Prozess einen verarbeiteten Datenblock (mit Sperre!) in die Ausgabedatei schreiben zu lassen. p>

Ein anderer Ansatz besteht darin, einen Master-Prozess zu erstellen, der den Schreibauftrag für den Rest der Prozesse ausführt, hier ist ein Beispiel.

BEARBEITEN

Nach dem Kommentar habe ich festgestellt, dass Sie die Datei nicht speichern können. Dazu können Sie einfach über das Dateiobjekt iterieren, das zeilenweise in den Speicher gelesen wird. Aber als wir den Code ein wenig groß ändern müssen:

%Vor%

Beachten Sie, dass Sie mit der Variablen CHUNK_SIZE spielen können, um zu steuern, wie viel Speicher Sie verwenden. Für mich 5000 ist ungefähr 10K maximal für jeden Prozess.

P.S

Ich denke, es wäre am besten, die große Datei in kleinere Dateien aufzuteilen, auf diese Weise löst man die Lese- / Schreibsperre für die Datei und macht sie skalierbar für die Verarbeitung (sogar auf einer anderen Maschine!)

    
Or Duan 01.11.2017, 17:17
quelle
0

Es sieht so aus, als ob line = next(fi) unter verschiedenen Process nicht korrekt verarbeitet wird.

Es ist möglich, die Verwendung von next(fi) mit Hilfe eines temporären Puffers von Zeilen zu umgehen, die vom Hauptthread des Programms gefüllt und von jedem Prozess gelesen werden. Für diese Rolle ist es besser, multiprocessing.Queue zu verwenden.

Das ist also mein Skript:

%Vor%

Auf meiner CPU habe ich folgendes Ergebnis:

%Vor%     
Fomalhaut 02.11.2017 08:43
quelle