2016-10-25 4 views
2

I testete Python Multiprozessing mit einem einfachen Programm:Python Objekte in Multi

class MyTest: 
    def __init__(self): 
     self.myattr = 1 

    def myfunc(self): 
     print(self) 
     self.myattr=2 
     print(self) 
     print("in proc"+str(self.myattr)) 



def main(): 

    test = MyTest() 
    print(test) 
    myProc = Process(target = test.myfunc,args=()) 

    myProc.start() 
    myProc.join() 
    print(test.myattr) 

main() 

Der Ausgang des Selbst in dem Verfahren, das der Prozess läuft, hat die gleiche Adresse wie die von dem Objekt in Haupt, die ich ziemlich seltsam gefunden, da sie getrennte Prozesse sind. Da sie sich jedoch an der gleichen Adresse befinden, werden sie tatsächlich über Prozesse verteilt, und das Attribut myattr in myfunc sollte das Attr des Tests in main ändern. print(test.myattr) druckt jedoch weiterhin 1, auch nachdem der Prozess die Aktualisierung des Attributs test beendet hat.

Meine erste Frage ist, warum teilen diese beiden Objekte in getrennten Prozessen die gleiche Adresse, und meine zweite ist, wenn sie die gleiche Adresse teilen, warum nicht Änderungen in einem Prozess durch Änderungen in einem anderen erkannt werden?

P.S. Hat meine erste Frage etwas mit der Tatsache zu tun, dass ich den Prozess eine Objektmethode übergebe, die als Ziel ausgeführt wird? d.h. ein Objektfunktionsaufruf wie test.myfunc = MyTest.myfunc (test).

Der Ausgang:

<__main__.MyTest object at 0x7f007bdf76d8> 
<__main__.MyTest object at 0x7f007bdf76d8> 
<__main__.MyTest object at 0x7f007bdf76d8> 
in proc2 
1 
+2

ich die Antwort denken könnte hier sein: http://stackoverflow.com/questions/20955683/python-multiprocessing sharing-a-complex-object und hier: http://StackOverflow.com/a/33701697/289011 (insbesondere der Teil, der sagt, dass _Adressenzeiger virtuell sind, deshalb stellen sie einen Offset innerhalb von t dar Er verarbeitet Adressraum selbst _) – BorrajaX

+1

Es muss also sein, dass der Hauptprozess und der Kindprozess zufällig das ursprüngliche Objekt (Hauptprozess) und das kopierte Objekt (Kindprozess) in ihren entsprechenden virtuellen Adressräumen in demselben Offset haben? – dylan7

+1

Das muss es sein ... Ich muss sagen, das hat mich auch verwirrt **: - S ** Es ist eine nette Frage (zumindest half es mir etwas zu lernen, dass ich dachte, es würde auf andere Weise funktionieren) – BorrajaX

Antwort

0

Ich glaube, Sie pathos verwenden sollen, vereinfacht es Multiprozessing mit Klassen und funktioniert wie ein Kinderspiel.

Schritt 1:

pip install pathos 

Schritt 2:

Code Umgestalten der Lage sein, ohne __init__() zu laufen, dann eine Klasse Methode, die ausgeführt wird, was Sie ausführen möchten , sollten die Instanzvariablen in der Klassenmethode sein, die Sie ausführen möchten.

Schritt 3:

Dann führen Sie es, wie Sie wollen.

Beispiel:

from pathos.multiprocessing import ProcessingPool as Pool 
p = Pool(4) 
class MyClass: 

    def add(self, x, y): 
     return x+y 

mc = MyClass() 
x = [1,2,3,4,5] 
y = [0,2,4,6,8] 
result = p.amap(mc.add, x, y) 
print result.get() 

Quelle: https://stackoverflow.com/a/21345308/7372029

https://github.com/uqfoundation/pathos/tree/master/examples