2

Я пытаюсь обновить ключ во вложенном словаре менеджера мультипроцессорного модуля manager.dict(), но не в состоянии это сделать. Он не обновляет значение и не вызывает никакой ошибки.Невозможно обновить значение вложенного словаря в диспетчере multiprocessing manager.dict()

Код:

import time 
import random 
from multiprocessing import Pool, Manager 

def spammer_task(d, token, repeat): 
    success = 0 
    fail = 0 
    while success+fail<repeat: 
     time.sleep(random.random()*2.0) 
     if (random.random()*100)>98.0: 
      fail+=1 
     else: 
      success+=1 
     d[token] = { 
      'status': 'ongoing', 
      'fail': fail, 
      'success': success, 
      'repeat': repeat 
     } 
    print d[token]['status'] 
    d[token]['status'] = 'complete' 
    return 

p = Pool() 
m = Manager() 
d = m.dict() 

p.apply_async(spammer_task (d, 'abc', 5)) 
print d 

Выход:

продолжается

{ 'а': { 'статус': 'продолжается', 'провал': 0, 'повтор': 5, 'success': 5}}

Мои ожидания заключаются в том, что как только цикл цикла завершится, он должен сделать d ['abc'] ['status'] = com plete. Но при окончательной печати он печатает свой статус только «продолжающийся».

ответ

3

не уверен, почему, но менеджер объекта DictProxy не может обрабатывать мутирующую вложенную часть. этот код работает:

import time 
import random 
from multiprocessing import Pool, Manager 

def spammer_task(d, token, repeat): 
    success = 0 
    fail = 0 
    while success+fail<repeat: 
     time.sleep(random.random()*2.0) 
     if (random.random()*100)>98.0: 
      fail+=1 
     else: 
      success+=1 
     d[token] = { 
      'status': 'ongoing', 
      'fail': fail, 
      'success': success, 
      'repeat': repeat, 
     } 
    print d[token]['status'] 
    foo = d[token] 
    foo['status'] = 'complete' 
    d[token] = foo 
    return 

p = Pool() 
m = Manager() 
d = m.dict() 

p.apply_async(spammer_task(d, 'abc', 5)) 
print d 
+0

Спасибо, никакое другое решение, используя дополнительную память? Я собираюсь деамонизировать этот многопроцессор внутри HTTP-сервера и не хочу обрабатывать дополнительную память + очистку для них. – MohitC

+0

Согласно примечанию в этой части документа: https://docs.python.org/2/library/multiprocessing.html#using-a-remote-manager - вышеизложенное представляется предлагаемым способом для этого. – domoarrigato

+0

Заметка, опубликованная @domoarrigato, устарела, но это правда, что официальная документация на Python утверждает, что этот ответ является правильным. Вот новая ссылка - прокрутите вниз чуть-чуть, чтобы найти «Примечание»: https://docs.python.org/2/library/multiprocessing.html#managers –

0

Похоже, этот вопрос остается на код ниже:

import multiprocessing, sys; 

if __name__ == '__main__': 

print(sys.version); 

mpd = multiprocessing.Manager().dict(); 
mpd['prcss'] = {'q' : 'queue_1', 'ctlg' : 'ctlg_1' }; 

# update 1 - doesn't work! 
mpd['prcss'].update({ 'name': 'concfun_1'}); 
print('Result of failed update 1:', mpd['prcss']); 

# update 2 - doesn't work! 
mpd['prcss']['name'] = 'concfun_1'; 
print('Result of failed update 2:', mpd['prcss']); 

# update 3 - works! 
mpd_prcss = mpd['prcss']; 
mpd_prcss['name'] = 'concfun_1'; 
mpd['prcss'] = mpd_prcss; 
print('Result of successful update 3:', mpd['prcss']); 

Выход:

3.6.1 (v3.6.1: 69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 бит (Intel)]

Результат неудачного обновления 1: {'q': 'Queue_1', 'ctlg': 'ctlg_1'}

Результат неудачного обновления 2: { 'д': 'queue_1', 'ctlg': 'ctlg_1'}

Результат успешного обновления 3: { 'д': 'queue_1', 'ctlg': 'ctlg_1', 'имя': 'concfun_1'}

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

  • Нет связанных вопросов^_^