multitraitement.Piscine avec une variable globale
Je suis en utilisant la Piscine de la classe de python multitraitement bibliothèque écrire un programme qui va s'exécuter sur un cluster HPC.
Ici est une abstraction de ce que je suis en train de faire:
def myFunction(x):
# myObject is a global variable in this case
return myFunction2(x, myObject)
def myFunction2(x,myObject):
myObject.modify() # here I am calling some method that changes myObject
return myObject.f(x)
poolVar = Pool()
argsArray = [ARGS ARRAY GOES HERE]
output = poolVar.map(myFunction, argsArray)
La fonction f(x) est contenu dans un *.donc, fichier, c'est à dire, c'est l'appel d'une fonction C.
Le problème que j'ai est que la valeur de la variable de sortie est différente à chaque fois que je lance mon programme (même si la fonction myObject.f() est une fonction déterministe). (Si j'ai seulement un processus, puis la variable de sortie est le même à chaque fois que je lance le programme.)
J'ai essayé de créer l'objet plutôt que de le stocker en tant que variable globale:
def myFunction(x):
myObject = createObject()
return myFunction2(x, myObject)
Cependant, dans mon programme, la création de l'objet est cher, et donc, c'est beaucoup plus facile de créer myObject une fois et ensuite modifier à chaque fois que j'appelle myFunction2(). Donc, je voudrais ne pas avoir à créer l'objet à chaque fois.
Avez-vous des conseils? Je suis très nouveau à la programmation parallèle, donc je pouvais aller au sujet de cette tout faux. J'ai décidé d'utiliser la Piscine de la classe car je voulais commencer par quelque chose de simple. Mais je suis prêt à essayer une meilleure façon de le faire.
- Pourriez-vous corriger de ce programme qui s'exécute? Déclaration des fonctions après vous essayez de les utiliser ne fonctionne pas en Python (et pourraient être utiles à votre problème)
- Est
myObject.modify()
idempotent? C'est, pouvez-vous appeler cela un nombre arbitraire de fois, sans changer ce qu'il fait (comme unreset()
fonction)? Si oui, ton code devrait fonctionner. Si non, vous aurez des problèmes, car les différents processus chaque modifier leur propre copie de l'objet, séparément les uns des autres, et ainsi vous pouvez obtenir des valeurs dupliquées à travers des processus. - Oui, myObject.modifier() est idempotent.
Vous devez vous connecter pour publier un commentaire.
Processus ne sont pas fils! Vous ne peut pas il suffit de remplacer
Thread
avecProcess
et s'attendent tous à fonctionner de la même.Process
es ne pas partager de la mémoire, ce qui signifie que les variables globales sont copié, donc leur valeur dans le processus d'origine ne change pas.Si vous souhaitez utiliser la mémoire partagée entre les processus, alors vous devez utiliser le
multiprocessing
's types de données, tels queValue
,Array
, ou utiliser leManager
à créer des listes etc.En particulier, vous pourriez être intéressé par le
Manager.register
méthode, qui permet à l'Manager
à créer des objets personnalisés(bien qu'ils doivent être picklable).Cependant, je ne suis pas sûr que cela permettra d'améliorer la performance. Depuis tout la communication entre les processus exige de décapage et de décapage prend habituellement plus temps, puis il suffit de l'instanciation de l'objet.
Notez que vous pouvez faire de l'initialisation du processus de travail en passant le
initializer
etinitargs
argument lors de la création de laPiscine
.Par exemple, dans sa forme la plus simple, pour créer une variable globale dans le processus de travail:
Utilisé comme:
Puis le travailleur fonctions peuvent utiliser le
data
variable globale sans soucis.Style note: Jamais utiliser le nom de built-in pour les variables/modules. Dans votre cas
object
est construit. Sinon vous vous retrouverez avec des erreurs inattendues qui peuvent être obscures et difficiles à dépister.