2016-12-30 3 views
1

Я хочу исследовать многопроцессорность. У меня есть «tar» архив, скажем, с 1000 файлами (на самом деле файлов гораздо больше), и каждый файл имеет 1000 строк. Мне нужно прочитать каждый файл и каждую строку файла. Мне нужно вернуть и сохранить информацию о каждом файле в некоторой переменной «result» (dictionary). У меня есть следующий код, и по какой-то неизвестной причине он останавливается после 8 итераций:Python Multiprocessing. Архив Loop с файлами

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() 

«для файла в self.tar» сделать только 8 итераций. Что я делаю неправильно?

ответ

1

Я вижу несколько проблем в опубликованном коде.

Главный процесс открывает файл, но не закрывает его. Если у вас есть 1K-файлы, у вас закончится дескрипторы файлов. Скорее передайте путь к дочернему процессу и дайте ему открыть его.

Также вы создадите процессы 1K, которые трудно обрабатывать на обычном компьютере. Вы сами управляете своими процессами, используя Pool, вы сократили бы большую сложность, упрощая свой код.

Насколько велика продукция, произведенная детскими процессами? Если он слишком велик, это может быть одной из причин, почему он застревает.

Последнее, что смешивание ООП и многопроцессорность - практика, подверженная ошибкам (AKA не передает себя детям).

Что-то вроде этого сократило бы большую часть бесполезной сложности (предполагая Python 2).

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

мощность не большой. Thx для советов. Попробуем и реализуем их. – Andrew