Seite 1 von 1

Zugriff auf Eigenschaften einer Klasseninstanz mit mehreren Prozessen

Verfasst: Freitag 4. September 2020, 11:09
von Martin1986
Hallo liebe Forenmitglieder,
ich bin vor einiger Zeit auf das Modul "multiprocessing" gestoßen und versuche gerade eine Funktion einer Klasseninstanz mit mehreren Prozessen zu starten. Dabei wird auf eine Eigenschaft der Instanz lesend zu gegriffen und eine zweite Eigenschaft geschrieben (String wird erweitert!). Wie schon erwähnt eben mit mehreren Prozessen
Wie zu erwarten funktioniert das nicht!

Daher meine Fragen an euch:
  • Ist die Herangehensweise überhaupt die Richtige?
  • Falls nein, wie würdet ihr das Problem lösen?
  • Falls ja, was fehlt noch um ein lauffähiges Script zu bekommen? Bzw. wo kann ich das nachlesen?
Ich habe ein kurzes übersichtliches MInimalbeispiel gemacht um die Problematik zu verdeutlichen!

Code: Alles auswählen

# -*- coding: utf-8 -*-
from multiprocessing import Process

class Test_Klasse:
    def __init__(self):
        # Eigenschaft welche erweitert wird
        self.erg_string = "Ergebnisse:\n"
        # lesender Zugriff auf Eigenschaft
        self.b_dict = {"A":1, "B":2, "C":3, "D":4, "E":5, "F":6}

    def gen_diff(self, zahlen_dict):
        '''
        Bildet Differenz aus zwei Zahlen
        und speichert Ergebnis als String in self.erg_string
        '''
        for i in zahlen_dict:
            erg = zahlen_dict[i] - self.b_dict[i]
            self.erg_string = self.erg_string + "{} = {}\n".format(i, str(erg))
        

if __name__ == "__main__":

    test_Dict_liste = [{"A":15, "B":14, "C":13}, {"D":12, "E":11, "F":10}]
    procs = []

    T = Test_Klasse()
##### Achtung, Quellcode funktioniert nicht #######   
    for t_dict in test_Dict_liste:
        proc = Process(target=T.gen_diff, args=(t_dict,))
        procs.append(proc)
        proc.start()

    for proc in procs:
        proc.join()
###################################################           
    print "Juhu!"
Vielen Dank für eure Hilfe schon im Vorraus!
Grüße Martin

Re: Zugriff auf Eigenschaften einer Klasseninstanz mit mehreren Prozessen

Verfasst: Freitag 4. September 2020, 12:44
von Sirius3
Der _ in Test_Klasse ist unnötig, da durch die groß-klein-Schreibung schon die einzelnen Bestandteile lesbar sind. Benutze keine Abkürzungen und Typen haben in Variablennamen auch nichts verloren: erg_string -> ergebnis, oder b_dict -> buchstaben? Was hat die Methoden gen_diff mit Genen zu tun? `i` ist ein sehr schlechter Name für einen Schlüssel, der einen Buchstaben repräsentiert.
Alles was unter if __name__ steht, sollte in eine Funktion wandern, die man üblicherweise main nennt.
Das Problem ist nicht für Multiprocessing geeignet, da Du von überall auf die selbe Datenstruktur zugreifst und veränderst.
Was Du eigentlich willst, ist gar keine Klasse, sondern eine Funktion, die aus zwei übergebenen Wörterbüchern einen String erzeugt.
Das kann man dann unabhängig für viele Wörterbucher per multiprocessing.Pool.map umwandeln lassen und im Hauptprogramm per join zu einem String verbinden.

Code: Alles auswählen

from multiprocessing import Pool
from functools import partial

def build_string(items_a, items_b):
    return "".join(f"{key} = {items_a[key] - items_b[key]}\n" for key in items_b)

def main():
    main_items = {"A":1, "B":2, "C":3, "D":4, "E":5, "F":6}
    test_items = [{"A":15, "B":14, "C":13}, {"D":12, "E":11, "F":10}]
    
    pool = Pool()
    ergebnis = "".join(pool.map(partial(build_string, main_items), test_items))
    print(ergebnis)

if __name__ == '__main__':
    main()
Was willst Du eigentlich machen? Was wäre Deine wirkliches Problem, das Du per multiprocessing zu lösen versuchst?

Re: Zugriff auf Eigenschaften einer Klasseninstanz mit mehreren Prozessen

Verfasst: Freitag 4. September 2020, 13:32
von Martin1986
Hallo Sirius3, danke für deine Antwort.
Ok, dass mit den Bezeichnungen werde ich in Zukunft beachten!
Naja, ich habe einen bestehenden Quelltext mit eine Klasse, die die Aufgabe hat, Dataframes (Pandas) voneinander zu subtrahieren (100000+ mal) (und andere Modifikationen der Dataframes) . Das klappt sehr gut und zuverlässig. Leider dauert das ganze eben eine gewisse Zeit. Daher kam mir die Idee, das ganze mit dem multiprocessing-Modul zu beschleunigen.
An deinen Vorschlag mit der map()-Funktion habe ich auch schon gedacht, aber das würde natürlich eine komplette Neuprogrammierung des Tools bedeuten. Mein Ziel war und ist es natürlich, den Änderungsaufwand so gering wie möglich zu halten (Never touch a running system!).

Dass ich mit mehreren Prozessen auf die selbe Datenstruktur zugreife ist mir bewusst. Ich bin im multiprocessing-Modul nicht wirklich fit und dachte es gibt irgendeine Möglichkeit.

Re: Zugriff auf Eigenschaften einer Klasseninstanz mit mehreren Prozessen

Verfasst: Freitag 4. September 2020, 13:43
von __deets__
Wenn du eine geteilte Datenstruktur haettest, muesste die wiederum muehselig vor gleichzeitigem Zugriff geschuetzt werden, weil es sonst zu Fehlern in der Berechnung kommt. Bringt also alles nix. Wenn du da Geschwindigkeit gewinnen willst, ist so etwas wie map/reduce tatsaechlich eine sehr gute Wahl.

Re: Zugriff auf Eigenschaften einer Klasseninstanz mit mehreren Prozessen

Verfasst: Freitag 4. September 2020, 13:45
von Sirius3
Große Matrixrechnungen können mit numpy+mkl schon automatisch auf mehrere Kerne per Multithreading verteilt werden. Das ist deutlich effizienter, da sich die Threads den Speicher teilen und deutlich einfacher zu programmieren, weil man nichts extra machen muss.

Klassen sollte man nur benutzen, wenn sie auch für das Programm sinnvoll sind. Dass man ein Tool mehrmals während der Entwicklung umstrukturieren muß, ist auch nichts ungewöhnliches. Das ist meist schnell gemacht und hilft, die Komplexität nicht unnötig wachsen zu lassen.

Wenn Du den tatsächlichen Code hier postest, können wir auch viel besser helfen.

Re: Zugriff auf Eigenschaften einer Klasseninstanz mit mehreren Prozessen

Verfasst: Freitag 4. September 2020, 14:21
von Martin1986
Vielen Dank für eure Antworten.
Ihr habt mir deutlich gemacht, dass es so nicht funktionieren wird.
Ich werde also nicht drumherum kommen, das Ganze umzubauen.
Einen schönen Tag noch.

Viele Grüße Martin