2016-12-30 12 views
1

Ich möchte Multiprozessing untersuchen. Ich habe 'tar' Archiv, sagen wir mit 1000 Dateien (tatsächlich gibt es viel mehr Dateien) und jede Datei hat 1000 Zeilen. Ich muss jede Datei und jede Zeile der Datei lesen. Ich muss zurück und speichern Sie Informationen über jede Datei in einigen 'Ergebnis' Variable (Wörterbuch). Ich habe nächsten Code und aus einem unbekannten Grunde hält es nach 8 Wiederholungen:Python Multiprocessing. Loop Archiv mit Dateien

class DataProc(): 
... 

def data_proc(self): 
    ... 
    result = {} 
    read_mode = 'r' 
    self.tar = tarfile.open(file_path, read_mode) 
    for file in self.tar: 
     q = Queue() 
     p = Process(target=process_tar, 
        args=(file, q)) 
     p.start() 
     tmp_result = q.get() 
     for key, item in tmp_result.items(): 
      ''' 
      do some logic and save data to result 
      ''' 
      pass 
     p.join() 
    return result 

def process_tar(self, file, q): 
    output = {} 
    extr_file = self.tar.extractfile(file) 
    content = extr_file.readlines() 
    ''' 
    do some data processing with file content 
    save result to output 
    ''' 
    q.put(output) 

dp = DataProc() 
result = dp.data_proc() 

‚für Datei in self.tar‘ machen nur 8 Wiederholungen. Was mache ich falsch?

Antwort

1

Ich sehe einige Ausgaben in dem gebuchten Code.

Der Hauptprozess öffnet die Datei, schließt sie aber nicht. Wenn Sie 1K-Dateien haben, werden Ihnen die Dateideskriptoren ausgehen. Übergeben Sie den Dateipfad lieber an den untergeordneten Prozess, und öffnen Sie ihn.

Außerdem spawnen Sie 1K-Prozesse, die auf einem normalen Computer schwer zu behandeln sind. Sie verwalten die Prozesse selbst, die Verwendung eines Pools würde viel Komplexität reduzieren und Ihren Code vereinfachen.

Wie groß ist der Output der Children-Prozesse? Wenn es zu groß ist, könnte es einer der Gründe sein, warum es stecken bleibt.

Die letzte Sache, mischen OOP und Multiprocessing ist eine ziemlich fehleranfällige Praxis (AKA nicht selbst an die Kinder Prozesse übergeben).

So etwas würde den größten Teil der nutzlosen Komplexität (unter der Annahme von Python 2) abschneiden.

from multiprocessing import Pool 

files_path = [ ... list of path of archive files ... ] 

def process_archive(file_path): 
    with open(file_path): 
     ... processing archive ... 

pool = Pool() 

for result in pool.map(function, files_path): 
    ... enjoy the results ... 
+0

Ausgabe ist nicht groß. Danke für die Ratschläge. Wird versuchen und sie implementieren. – Andrew