2

Ich versuche, einen Schlüssel in einem verschachtelten Wörterbuch des multiprocessing Modul manager.dict() zu aktualisieren, aber nicht in der Lage, dies zu tun. Es aktualisiert den Wert nicht und wirft auch keinen Fehler.Fehler beim Aktualisieren des geschachtelten Wörterbuchwerts in Multiprocessing manager.dict()

Code:

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 

Ausgang:

laufenden

{ 'abc': { 'Status': 'laufende', 'fail': 0, 'Wiederholung': 5, 'Erfolg': 5}}

Meine Erwartungen sind, dass, sobald while-Schleife endet, sollte es d [ 'abc'] [ 'Status'] = machen com plete. Beim letzten Druck wird jedoch nur der Status 'fortlaufend' ausgegeben.

Antwort

3

nicht sicher, warum, aber das Manager-DictProxy-Objekt scheint nicht mit der Mutation eines verschachtelten Teils umzugehen. Dieser Code funktioniert:

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

Danke, keine andere Lösung, die unter Verwendung von zusätzlichen Speichern? Ich werde diesen Multiprozessor innerhalb eines HTTP-Servers deamonisieren und habe nicht das Gefühl, zusätzlichen Speicher + Bereinigung für sie zu behandeln. – MohitC

+0

Laut dem Hinweis unter diesem Teil der Dokumentation: https://docs.python.org/2/library/multiprocessing.html#using-a-remote-manager - scheint das oben vorgeschlagene Verfahren zu sein. – domoarrigato

+0

Die Nachricht, die @domoarrigato gepostet hat, ist veraltet - aber es ist wahr, dass die offizielle Python-Dokumentation diese Antwort als richtig angibt. Hier ist der neue Link - scrollen Sie nach unten, um die Notiz zu finden: https://docs.python.org/2/library/multiprocessing.html#managers –

0

wie dieses Problem Sieht bleibt pro Code unten:

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']); 

Ausgang:

3.6.1 (v3.6.1: 69c0db5, 21. März 2017, 17:54:52) [MSC v.1900 32 bit (Intel)]

Ergebnis der fehlgeschlagenen Aktualisierung 1: {'q': 'Queue_1', 'CTLG': 'ctlg_1'}

Ergebnis gescheiterten Update 2: { 'q': 'queue_1', 'CTLG': 'ctlg_1'}

Ergebnis erfolgreichen Update 3: { 'q': 'queue_1', 'CTLG': 'ctlg_1', 'name': 'concfun_1'}