La première question est quelle est la différence entre Value et Manager (). Value?
Deuxièmement, est-il possible de partager une variable entière sans utiliser Value? Voici mon exemple de code. Ce que je veux, c'est obtenir un dict avec une valeur entière, pas Value. Ce que j'ai fait, c'est de tout changer après le processus. Existe-t-il un moyen plus simple?
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
Lorsque vous utilisez Value
vous obtenez un objet ctypes
dans la mémoire partagée qui, par défaut, est synchronisé à l'aide de RLock
. Lorsque vous utilisez Manager
vous obtenez un objet SynManager
qui contrôle un processus serveur qui permet aux valeurs d'objet d'être manipulées par d'autres processus. Vous pouvez créer plusieurs proxys en utilisant le même gestionnaire; il n'est pas nécessaire de créer un nouveau gestionnaire dans votre boucle:
manager = Manager()
for i in range(5):
new_value = manager.Value('i', 0)
Manager
peut être partagé entre plusieurs ordinateurs, tandis que Value
est limité à un ordinateur. Value
sera plus rapide (exécutez le code ci-dessous pour voir), donc je pense que vous devriez l'utiliser à moins que vous n'ayez besoin de prendre en charge des objets arbitraires ou d'y accéder via un réseau.
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)
Pour résumer:
Manager
pour créer plusieurs objets partagés, y compris des dict et des listes. Utilisez Manager
pour partager des données entre les ordinateurs d'un réseau.Value
ou Array
lorsqu'il n'est pas nécessaire de partager des informations sur un réseau et que les types dans ctypes
sont suffisants pour vos besoins.Value
est plus rapide que Manager
.Avertissement
Soit dit en passant, le partage des données entre les processus/threads doit être évité si possible. Le code ci-dessus s'exécutera probablement comme prévu, mais augmentez le temps nécessaire pour exécuter foo
et les choses deviendront étranges. Comparez ce qui précède avec:
def foo(data, name=''):
print type(data), data.value, name
for j in range(1000):
data.value += 1
Vous aurez besoin d'un Lock
pour que cela fonctionne correctement.
Je ne suis pas particulièrement bien informé sur tout cela, alors peut-être que quelqu'un d'autre viendra et offrira plus d'informations. J'ai pensé que j'apporterais une réponse car la question n'attirait pas l'attention. J'espère que ça aide un peu.