Multiprocessing Anfängerproblem

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
incoggnito
User
Beiträge: 53
Registriert: Donnerstag 27. April 2017, 09:28

Servus Zusammen,

ist jemand klar, warum ich mit folgendem Code in einer Dauerschleife lande:
(Vorsicht der Code ist etwas symbolisch)

Code: Alles auswählen

from multiprocessing import Pool
from tkinter import filedialog
import tkinter as tk

def do_sth(file_str):
    #öffne das file und lese die Datenarrays
    #berechne einen einzelnen Ergebniswert
    return value_int

if __name__ == "__main__": #sonst werden zig Fenster geöffnet, hab noch nicht so richtig verstanden warum ...
    root = tk.Tk()
    root.withdraw()
    files = filedialog.askopenfilenames(
            initialdir=projectpath,
            title='Please select the files to compare',)
            
files = list(files) #sonst wird ein tuple ausgegeben

p = Pool()
result = p.map(do_sth, files)

ohne pool() mit:

Code: Alles auswählen

result = list(map(do_sth,files))
funktioniert der code soweit ...

Vielen Dank an alle Helfer
inco
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Also in diesem sehr allgemein gehaltenen Code ist kein Programmierfehler zu sehen. Da müsstest du schon konkreter werden. Insbesondere würde es uns helfen, wenn du sagst, was do_sth() tatsächlich tut. Aus dem Kommentar jedenfalls lässt sich der Grund für die Endlosschleife nicht ableiten.
incoggnito
User
Beiträge: 53
Registriert: Donnerstag 27. April 2017, 09:28

Danke für die Rückmeldung. Die Methode kann ich aktuell leider nicht veröffentlichen.
Aber auch mit diesem einfachen Sample münde ich in einer Endlosschleife:

Code: Alles auswählen

from asammdf import MDF
from multiprocessing import Pool
from tkinter import filedialog
import tkinter as tk
import numpy as np

def do_sth(file_str):
    mdf = MDF(file_str)   
    data = mdf.get('Channelname')
    a_z = data.samples
    return np.mean(a_z)

if __name__ == "__main__": #sonst werden zig Fenster geöffnet, hab noch nicht so richtig verstanden warum ...
    root = tk.Tk()
    root.withdraw()
    files = filedialog.askopenfilenames(
            initialdir=projectpath,
            title='Please select the files to compare',)
            
files = list(files) #sonst wird ein tuple ausgegeben

p = Pool()
result = p.map(do_sth, files)
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@incoggnito: Das gleiche Problem was Du auch schon in dem Kommentar beschreibst. Das Modul muss sich importieren lassen können *ohne* das irgendwas passiert ausser das Konstanten, Funktionen, und Klassen definiert werden. Das sollte man sowieso so machen. Der gesamte Code nach dem ``if`` gehört *in* den ``if``-Zweig oder besser noch in eine eigene Funktion die von dort aufgerufen wird.

@snafu: Kann sein das Du kein Windows verwendest, denn AFAIK gibt es nur dort dieses Problem, weil es kein `fork()` auf Systemebene gibt. Deshalb wird von `multiprocessing` ein neuer Prozess gestartet der das `__main__`-Modul erneut importiert. Und wenn da beim Import `multiprocessing` was ausführt, geht dieses Spielchen rekursiv, endlos weiter.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
incoggnito
User
Beiträge: 53
Registriert: Donnerstag 27. April 2017, 09:28

Ok, danke für den Hinweis. Es läuft nun, bringt aber leider keinen zeitlichen Vorteil.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ist halt immer die Frage was man parallelisiert. Wenn man ”nur” viele Dateien parallel lädt, dann kloppen sich halt entsprechend viele Prozesse gleichzeitig um den Datendurchsatz zum Hintergrundspeicher und eventuell auch um den verfügbaren Hauptspeicher.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
incoggnito
User
Beiträge: 53
Registriert: Donnerstag 27. April 2017, 09:28

Das Problem saß vor dem Rechner ... hab nicht gesehen, dass das Netzwerk an der Grenze seiner Möglichkeiten war.
Da bin ich dann einfach an den Grenzen meiner Arbeitsumgebung ;)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn es Netzwerkverkehr ist, dann kann Threading was bringen, um damit mehrere Verbindungen gleichzeitig zu betreiben. Jetzt ist halt die Frage ob das Netzwerk tatsächlich ausgelastet ist oder ob du es nur glaubst...
incoggnito
User
Beiträge: 53
Registriert: Donnerstag 27. April 2017, 09:28

Ok, da stecke ich zu wenig in der Thematik.
Taskmanger --> Auslastung 100%. 100MBits...
Recherchiere mal wie das Netzwerk Threading funzt.
Habe aber wenig Hoffnung, hänge an einem großen Firmennetzwerk. ;)
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

snafu hat geschrieben: Mittwoch 5. September 2018, 15:26 Wenn es Netzwerkverkehr ist, dann kann Threading was bringen, um damit mehrere Verbindungen gleichzeitig zu betreiben. Jetzt ist halt die Frage ob das Netzwerk tatsächlich ausgelastet ist oder ob du es nur glaubst...
Threading bringt nichts an sich, sondern kann bei IO-lastigen Aufgaben genutzt werden, weil das warten auf IO die Ausfuehrung dominiert. Da der TE aber schon eine multiprocessing-Loesung hat, wird es nichts aendern, wenn seine Leitung schon saturiert ist.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Genau weil es I/O-lastig ist, hatte ich es eingebracht...
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja. Und es bringt nichts das einzubringen, wenn die Lösung schon parallelisiert IST. Das hab ich eingebracht.
danielhrisca
User
Beiträge: 4
Registriert: Mittwoch 7. November 2018, 20:37

Sie können den Netzwerkverkehr reduzieren, wenn Sie das MDF memory argument auf "minimum" setzen.

(Siehe Dokumentation https://asammdf.readthedocs.io/en/lates ... y-argument)

Wenn Sie sich nicht für die Zeitstempel interessieren, können Sie auch samples_only als True im get setzen.

Code: Alles auswählen

def do_sth(file_str):
    mdf = MDF(file_str, memory='minimum')   
    a_z, _ = mdf.get('Channelname', samples_only=True)
    return np.mean(a_z)
    
Antworten