2015-02-03 5 views
4

Я хочу, чтобы понять, как многопроцессорная и менеджер работа с целью общей памятьюPython многопроцессорных совместно Dict внутри класса

У меня есть класс со словарем, созданным на классе. init Я хочу использовать многопроцессорную обработку, чтобы вызвать функцию класса, которая заполняет словарь (каждый процесс добавляет другой ключ).

import multiprocessing as mp 
from multiprocessing import Process, Manager 

class num: 
    def __init__(self): 
     manager = Manager() 
     d = manager.dict() 

     # Setup list of processes 
     processes = [mp.Process(target=self.f, args=(d,i)) for i in range(5)] 

     #Run processes 
     for p in processes: 
      p.start() 

     #Exit the completed processes 
     for p in processes: 
      p.join() 

     print d 

    def f(self,d,i): 
     d[str(i)] = [] 
     d[str(i)].append(i) 


if __name__ == '__main__':  
    test = num() 

результат:

{'1': [], '0': [], '3': [], '2': [], '4': []} 

Список внутри F() должны быть разделены тоже? Как и почему?

+0

Вопрос после ответа на ДНК, чтобы быть более конкретным –

ответ

3

Вам нужно изменить строку в функции f от:

d['i'] = [i] 

к чему-то вроде

d[str(i)] = i 

так, что ваши процессы не перезаписать одну записи чужие в общей Dict. После этого, она отлично работает для меня (в Python 2.7.3), распечатав

{'1': 1, '0': 0, '3': 3, '2': 2, '4': 4} 

(Кроме того, код размещен отсутствует в import multiprocessing as mp)

Update: если вы просто хотите значения в shared dict должны быть списками, то это простое изменение, например

d[str(i)] = [i] 

Если вы хотите, чтобы каждый из списков, которые будут общими для всех процессов, то вы, вероятно, необходимо создать эти списки в главном процессе, используя manager.list(), и передавать их на все подпроцессы, например:

count = 5 
    lists = [manager.list() for i in range(count)] 
    for i in range(count): 
     d[i] = lists[i] 
    processes = [mp.Process(target=self.f, args=(d,i, lists)) for i in range(count)] 

[...]

def f(self,d,i, lists): 
    for j in range(i):  # just an example to show 
     lists[j].append(i) # that the lists are shared between processes 

Я также попытался непосредственно вложенности управляемые списки внутри управляемой Dict, но по какой-то причине это не сработало, и subproc esses не смог обновить списки. Передача их отдельно, как показано, кажется, работает, например. Я могу получить каждый подпроцесс обновить несколько списков:

{0: [1, 2, 3, 4], 1: [2, 3, 4], 2: [3, 4], 3: [4], 4: []} 
+0

Спасибо! Я уточняю вопрос, чтобы быть более конкретным. Мне нужны значения dict, чтобы быть списками - нужно также делиться памятью списка? как? –

2

замена:

d[str(i)].append(i) 

с:

d[str(i)] += [i] 

решить эту проблему.

Результат:

{'1': [1], '0': [0], '3': [3], '2': [2], '4': [4]} 

Но я действительно хочу знать, почему.

Смежные вопросы