Seite 1 von 1
[Multiprocessing] komisches Verhalten
Verfasst: Sonntag 30. Mai 2021, 09:43
von TenchiMuyo1984
Hallo zusammen,
ich bin dabei mich etwas in die Thematik Multiprocessing einzuarbeiten. Dabei bin ich auf etwas gestoßen, was aus meiner Sicht keinen Sinn ergibt.
Hier der Code:
Code: Alles auswählen
import multiprocessing as mp
from multiprocessing import Process
import time
print(mp.cpu_count())
def myfunc(s_string, i_wait):
time.sleep(i_wait)
print(f'time from {s_string} exceeded')
if __name__ == '__main__':
proc_a = Process(target=myfunc('a', 2))
print('a created')
proc_b = Process(target=myfunc('b', 4))
print('b created')
proc_c = Process(target=myfunc('c', 6))
print('c created')
proc_a.start()
proc_b.start()
proc_c.start()
proc_a.join()
proc_b.join()
proc_c.join()
Und hier die Ausgabe:
Code: Alles auswählen
8
time from a exceeded
a created
time from b exceeded
b created
time from c exceeded
c created
8
8
8
Nun zu den Punkten, die ich nicht verstehe.
- Warum wird Linie 5 insgesamt 4 mal ausgeführt?
Habe da zwar eine Vermutung, welche für mich aber keinen Sinn ergibt:
Sie wird beim Ausführen einmalig und dann in jeden Process nochmals ausgeführt.
Aber die Abfrage ist doch nicht Teil der Funktion "myfunc()", die ich später den Prozessen zuweise.
- Warum werden die Prozesse "proc_x" ausgeführt bevor ich sie über "proc_x.start()" starte?
Ich hoffe ihr könnt mir da helfen.
Grüße
TenchiMuyo1984
Re: [Multiprocessing] komisches Verhalten
Verfasst: Sonntag 30. Mai 2021, 09:50
von __deets__
Du begehst den üblichen Fehler: statt als Target ein callable zu übergeben, übergibst du den Rückgabewert des Aufrufs. Der None ist. Schau dir nochmal ganz genau die Beispiele an, und wo da Klammern sind, und wo nicht.
Re: [Multiprocessing] komisches Verhalten
Verfasst: Sonntag 30. Mai 2021, 10:10
von Thants
Zum ersten Punkt, das steht in der Dokumentation unter "Programming Guidelines". Je nach Start-Methode wird das Hauptmodul in den neuen Prozessen nochmal importiert, weshalb Zeile 5 dann mehrfach ausgeführt wird. In deinem eigentlichen Programm solltest du also direkt auf Modul-Ebene keinen Code haben, der sofort ausgeführt wird.
Re: [Multiprocessing] komisches Verhalten
Verfasst: Sonntag 30. Mai 2021, 10:27
von TenchiMuyo1984
__deets__ hat geschrieben: Sonntag 30. Mai 2021, 09:50
Du begehst den üblichen Fehler: statt als Target ein callable zu übergeben, übergibst du den Rückgabewert des Aufrufs. Der None ist. Schau dir nochmal ganz genau die Beispiele an, und wo da Klammern sind, und wo nicht.
Ahhhh,
habe das schlicht vergessen
Thants hat geschrieben: Sonntag 30. Mai 2021, 10:10
Zum ersten Punkt, das steht in der Dokumentation unter "Programming Guidelines". Je nach Start-Methode wird das Hauptmodul in den neuen Prozessen nochmal importiert, weshalb Zeile 5 dann mehrfach ausgeführt wird. In deinem eigentlichen Programm solltest du also direkt auf Modul-Ebene keinen Code haben, der sofort ausgeführt wird.
Also alles in?:
Habs nun so gemacht:
Code: Alles auswählen
import multiprocessing as mp
from multiprocessing import Process
import time
def myfunc(s_string, i_wait):
time.sleep(i_wait)
print(f'time from {s_string} exceeded')
if __name__ == '__main__':
print(mp.cpu_count())
proc_a = Process(target=myfunc, args=('a', 2))
print('a created')
proc_b = Process(target=myfunc, args=('b', 4))
print('b created')
proc_c = Process(target=myfunc, args=('c', 6))
print('c created')
proc_a.start()
proc_b.start()
proc_c.start()
proc_a.join()
proc_b.join()
proc_c.join()
Und die Ausgabe sieht wie folgt aus:
Code: Alles auswählen
8
a created
b created
c created
time from a exceeded
time from b exceeded
time from c exceeded
Danke!
Re: [Multiprocessing] komisches Verhalten
Verfasst: Sonntag 30. Mai 2021, 12:20
von tonikae
Nur mal interesshalber nachgefragt
Gibt es da keine "Task-Map" in der man seine Tasks in einem Block zusammenpacken und starten kann?
Bsp:
Nix Weltbewegendes - ich will drei Tasks gleichzeitig starten und wissen welcher Task am schnellsten beendet ist.
Dafür eben eine "Task-Map"
https://drive.google.com/file/d/1NDZVP ... kLQ97/view
Wie macht man das in Python?
Re: [Multiprocessing] komisches Verhalten
Verfasst: Sonntag 30. Mai 2021, 12:50
von __deets__
Meinst du einen Pool?
https://docs.python.org/3/library/multi ... .pool.Pool
Das kann parallel rechnen, und da erste Ergebnis kommt zuerst zurück, wenn man zb imap benutzt.
Re: [Multiprocessing] komisches Verhalten
Verfasst: Montag 31. Mai 2021, 05:14
von tonikae
"pool" war zwar nicht ganz das(konkurrierend parallele Tasks kenne ich etwas anders) , aber trotzdem hilfreiche Antwort.....vielen Dank
Re: [Multiprocessing] komisches Verhalten
Verfasst: Montag 31. Mai 2021, 05:45
von sparrow
@tonikae: Du solltest Code immer als Text in Code-Tags einstellen. Nicht als Link auf einen Screenshot. Die kaputte Einrückung dort hast du bemerkt? Auch wenn Julia mit End-Tags arbeitet, hilft es beim Lesen erheblich, wenn die in der richtigen Ebene stehen.
Ich sehe nicht die Besonderheit in dem Code auf dem Screenshot. Du tust die "Tasks" ja einfach in eine Datenstruktur. Das ist ja nichts Sprachspezifisches sondern sollte sich in jeder Sprache umsetzen lassen, die Datenstrukturen kennt und bei denen die Tasks/Threads/Nebenläufigkeiten etwas sind, das man dort hinein stecken kann.
Re: [Multiprocessing] komisches Verhal
Verfasst: Montag 31. Mai 2021, 09:18
von __deets__
Ich verstehe nicht, wo der große Unterschied ist. Weil man ein Pool Objekt braucht? Denn die Nutzung sieht doch nahezu gleich aus. Ich kenne Julia nur vom gelegentlich drüber lesen, und kann mir gut vorstellen, dass da Entscheidungen zugunsten “einfach mathematische Probleme lösen” getroffen wurden. Also eben einen impliziten worker Pool, statt explizit, weil es angenehmer zu nutzen ist. Wenn dir das wichtig ist, kannst du auch eine Hilfsmodul mit einem globalen Pool und einer daraus gezogenen task_map Funktion schreiben. Oder ist da sonst noch ein Unterschied, den ich nicht sehe?