it-swarm.com.de

Geteilte Variable in der Mehrfachverarbeitung von Python

Die erste Frage ist, was ist der Unterschied zwischen Value und Manager (). Value?

Ist es zweitens möglich, eine Ganzzahlvariable ohne Verwendung von Value gemeinsam zu nutzen? Unten ist mein Beispielcode. Was ich will, ist ein Diktat mit einem Wert von Integer, nicht Value. Was ich getan habe, ist einfach alles nach dem Prozess zu ändern. Gibt es einen einfacheren Weg?

from multiprocessing import Process, Manager

def f(n):
    n.value += 1

if __name__ == '__main__':
    d = {}
    p = []

    for i in range(5):
        d[i] = Manager().Value('i',0)
        p.append(Process(target=f, args=(d[i],)))
        p[i].start()

    for q in p:
        q.join()

    for i in d:
        d[i] = d[i].value

    print d
25
user2435611

Wenn Sie Value verwenden, erhalten Sie ein ctypes - Objekt im gemeinsam genutzten Speicher, das standardmäßig mit RLock . Wenn Sie Manager verwenden, erhalten Sie ein SynManager -Objekt, das einen Serverprozess steuert, mit dem Objektwerte von anderen Prozessen bearbeitet werden können. Sie können mit demselben Manager mehrere Proxys erstellen. Es ist nicht erforderlich, einen neuen Manager in Ihrer Schleife zu erstellen:

manager = Manager()
for i in range(5):
    new_value = manager.Value('i', 0)

Das Manager kann von mehreren Computern gemeinsam genutzt werden, während Value auf einen Computer beschränkt ist. Value ist schneller (führen Sie den folgenden Code aus, um zu sehen), daher sollten Sie diesen verwenden, es sei denn, Sie müssen beliebige Objekte unterstützen oder über ein Netzwerk darauf zugreifen.

import time
from multiprocessing import Process, Manager, Value

def foo(data, name=''):
    print type(data), data.value, name
    data.value += 1

if __name__ == "__main__":
    manager = Manager()
    x = manager.Value('i', 0)
    y = Value('i', 0)

    for i in range(5):
        Process(target=foo, args=(x, 'x')).start()
        Process(target=foo, args=(y, 'y')).start()

    print 'Before waiting: '
    print 'x = {0}'.format(x.value)
    print 'y = {0}'.format(y.value)

    time.sleep(5.0)
    print 'After waiting: '
    print 'x = {0}'.format(x.value)
    print 'y = {0}'.format(y.value)

Zusammenfassend:

  1. Verwenden Sie Manager, um mehrere gemeinsam genutzte Objekte zu erstellen, einschließlich Dikten und Listen. Verwenden Sie Manager, um Daten auf Computern in einem Netzwerk gemeinsam zu nutzen.
  2. Verwenden Sie Value oder Array, wenn es nicht erforderlich ist, Informationen über ein Netzwerk auszutauschen, und die Typen in ctypes für Ihre Anforderungen ausreichen.
  3. Value ist schneller als Manager.

Warnung

Im Übrigen sollte der Austausch von Daten zwischen Prozessen/Threads nach Möglichkeit vermieden werden. Der obige Code wird wahrscheinlich wie erwartet ausgeführt, aber die Ausführungszeit für foo verlängert sich und die Dinge werden merkwürdig. Vergleichen Sie das Obige mit:

def foo(data, name=''):
    print type(data), data.value, name
    for j in range(1000):
        data.value += 1

Sie benötigen ein Lock, damit dies korrekt funktioniert.

Ich bin nicht besonders gut informiert über all das, also wird vielleicht jemand anderes mitkommen und mehr Einsicht bieten. Ich nahm an, dass ich eine Antwort beisteuern würde, da die Frage nicht beachtet wurde. Hoffe das hilft ein wenig.

31
ChrisP