multiprocessing und class

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Pookie
User
Beiträge: 8
Registriert: Freitag 6. März 2015, 10:21

Hallöchen,

also mein Problem besteht darin, dass ich im endeffekt eine Methode einer Klasse per multiprocessing nutzen will und das einfach ohne Fehlermeldung nicht funktioniert (d.h. es kommt wirklich keine Fehlermeldung es macht einfach irgendwas, aber nicht was es soll). Der Code für das multiprocessing mit einer "normalen" Funktion außerhalb einer Klasse funktioniert. Im Prinzip sieht der Code so aus wie unten, das soll auch wirklich nur das Prinzip darstellen. Mein Ziel wäre den unteren Teil auch noch irgendwie auszulagern aber das funktioniert dann genauso wenig. Ich würde halt gern das "zu berechnende Problem" und die methoden, welche es dann zb für gewisse parameter lösen irgendwie trennen damit alles nicht zu unübersichtlich wird. Eventuell gibt es da ja auch bessere Ansätze.

Code: Alles auswählen

# das sind die module die ich im original nutze
from numpy import *
from scipy.integrate import odeint
from multiprocessing import Pool

class bla:
    def a(x):
        macht was
    def b(x,y):
        return 2*a(x)  # im sinne das hier methode b auch wirklich nochmal methode a intern nutzt

result = []
def callback_func(x):
    result.append(x)

def multi():
    pool = Pool(4)
    for i in linspace(1,2,3):
        pool.apply_async(blabla.b,args=(i,0,),callback=callback_func)
    pool.close()
    pool.join()        
    print(sorted(result))

blabla = bla()
multi()
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

So geht's

Code: Alles auswählen

from numpy import *
from scipy.integrate import odeint
from multiprocessing import Pool
 
class bla:
    def a(self, x):
        return 1.1*x
    def __call__(self, x,y):
        return 2*self.a(x)  # im sinne das hier methode b auch wirklich nochmal methode a intern nutzt
 
result = []
def callback_func(x):
    result.append(x)
 
def multi():
    pool = Pool(4)
    for i in linspace(1,2,3):
        pool.apply_async(blabla,args=(i,0),callback=callback_func)
    pool.close()
    pool.join()        
    print(sorted(result))
 
blabla = bla()
multi()
und hier steht warum:
http://stackoverflow.com/questions/1816 ... ng-pool-ma
a fool with a tool is still a fool, www.magben.de, YouTube
Pookie
User
Beiträge: 8
Registriert: Freitag 6. März 2015, 10:21

Ich muss gestehen, dass die Variante bei mir nicht funktioniert. Ich hab mir auch mal den Link angeschaut und versucht
You could also define a __call__() method inside your someClass(), which calls someClass.go() and then pass an instance of someClass() to the pool. This object is pickleable and it works fine (for me)...
umzusetzen (was ja fast deine Variante ist) jedoch auch ohne Erfolg, wenngleich das wohl eher an meinem Unvermögen liegen wird :K
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Pookie hat geschrieben:Ich muss gestehen, dass die Variante bei mir nicht funktioniert.
Hast Du meinen Code komplett kopiert und ausprobiert oder hast Du in Deinem Code die Methode b durch __call__ ersetzt? (Es gab in Deinem Code nämlich noch mehr Fehler.)
a fool with a tool is still a fool, www.magben.de, YouTube
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

"Funktioniert nicht" ist etwas unspezifisch und wenig hilfreich für uns. Was genau funktioniert denn nicht? Gibt es eine Fehlermeldung? Fackelt der PC ab? Bellt dein Hund? Du müsstest da schon etwas spezifischer werden: Was genau funktioniert nicht, wie wirkt sich das aus. Gibt es eine Fehlermeldung? Was besagt die und wie lautet der Traceback dazu?

*-Importe solltest du dir bei der Gelegenheit gleich abgewöhnen, die machen ein Programm nur unleserlich, unübersichtlich und die Herkunft von Namen nur schwer nachvollziehbar. Im schlimmsten Fall überschreibst du dir versehentlich andere Namen. Gerade bei numpy ist ein *-Import keine gute Idee, das füllt den gesamten Namensraum um über 500 Werte an.
Das Leben ist wie ein Tennisball.
BlackJack

Man sollte auch die ganzen Programmierrichtlinien aus der Dokumentation befolgen. Zum Beispiel das das Hauptmodul nebeneffektfrei importiert werden können muss ist zwar nur für Windows zwingend notwendig bei `multiprocessing`, aber generell für jedes Modul eine gute Idee.
Pookie
User
Beiträge: 8
Registriert: Freitag 6. März 2015, 10:21

Erstmal danke für die Antworten, ich versuche da mal alles etwas zu spezifizieren. Zunächst nutze ich das fertige Packet Anaconda mit Python 3.4 auf Win-64-bit. Als IDE nutze ich Spyder, welche bei Anaconda mit dabei ist und dort führe ich das Programm in einer IPython console aus.
MagBen hat geschrieben:Hast Du meinen Code komplett kopiert und ausprobiert oder hast Du in Deinem Code die Methode b durch __call__ ersetzt? (Es gab in Deinem Code nämlich noch mehr Fehler.)
Sowohl als auch. Mein Code hier war auch nur eine "Skizze" und mein originaler Code sollte keine so offensichtlichen Fehler enthalten. Aber auch komplett kopiert funktioniert es nicht.
Das komische ist einfach, dass wirklich keine Fehlermeldung aufkommt... als ich das schrieb kam mir die Idee anstatt der IPython mal die normale Python console zu nutzen und dort kam doch ein Fehler:
Der Traceback is relativ länglich
File "F:\Anaconda3\lib\multiprocessing\spawn.py", line 137, in _check_not_importing_main
is not going to be frozen to produce an executable.''')
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:

if __name__ == '__main__':
freeze_support()
...

The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
Ausgeführt wurde dieser Code in o.g. Umgebung:

Code: Alles auswählen

from numpy import linspace
from multiprocessing import Pool
     
class bla:
    def a(self, x):
        return 1.1*x
    def __call__(self, x,y):
        return 2*self.a(x)  # im sinne das hier methode b auch wirklich nochmal methode a intern nutzt
     
result = []
def callback_func(x):
    result.append(x)
     
def multi():
    pool = Pool(4)
    for i in linspace(1,2,3):
        pool.apply_async(blabla,args=(i,0),callback=callback_func)
    pool.close()
    pool.join()
    print(sorted(result))
   
blabla = bla()
multi()
EDIT:

Da ich den Fehler echt erst beim schreiben des Posts gefunen habe, habe ich erstmal abgeschickt. Aber nun nach ein wenig google bin ich auf:

Code: Alles auswählen

from numpy import linspace
from multiprocessing import Pool
     
class bla:
    def a(self, x):
        return 1.1*x
    def __call__(self, x,y):
        return 2*self.a(x)  # im sinne das hier methode b auch wirklich nochmal methode a intern nutzt
     
result = []
def callback_func(x):
    result.append(x)
     
def multi():
    pool = Pool(4)
    for i in linspace(1,2,3):
        pool.apply_async(blabla,args=(i,0),callback=callback_func)
    pool.close()
    pool.join()
    print(sorted(result))   

if __name__ == '__main__':
    blabla = bla()
    multi()
gekommen was sogar funktioniert.
Antworten