Python Skript aufrufen Main vs. Subprocess

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
Hakan
User
Beiträge: 38
Registriert: Mittwoch 8. Februar 2017, 12:13

Hallo liebes Forum,

ich habe 2 Python Skripte programmiert welche beide aufgerufen werden sollen. Nun stellt sich für mich die Frage ob ich die Skripte zu einem ganzen Skript zusammenfasse und eine Haupt Main deklariere oder ob ich in ein drittes Skript eine Main schreibe und durch das Modul subprocess die beiden Skripte aufrufe. Mich interessiert welche Variante eine bessere Performance darstellt. Zudem funktioniert das aufrufen durch subprocess noch nicht ganz fehlerfrei.

Beste Grüße
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hakan: bei der dürftigen Information über die Skripte kann man gar nichts sagen. Was für Fehler treten denn auf?
Hakan
User
Beiträge: 38
Registriert: Mittwoch 8. Februar 2017, 12:13

@Sirius3,
wenn du das so siehst dann sag doch einfach gar nichts :-). Also ich frage erneut wie sieht es aus mit der Performance Zugriff von außen durch ein drittes Skript oder beide Skripts in ein ganzes zusammenführen? Welcher Prozess ist für Python belastender?
BlackJack

@Hakan: Logischerweise der mit den mehreren Prozessen. Allerdings sollte das egal sein, weil das so wenig Unterschied ist, das Du davon eh nichts merken solltest. Allerdings sind beide Ansätze auch eher ungewöhnlich. Man würde das eher so schreiben das es keine eigenständigen Programme sind, oder das sie zumindest auch als Module benutzbar sind, und dann in *einem* Python-Prozess die beiden Module importieren und die entsprechenden Funktionen aufrufen.
Hakan
User
Beiträge: 38
Registriert: Mittwoch 8. Februar 2017, 12:13

@Blackjack
Man würde also die Funktionen welche man deklariert hat in ein Modul zusammenfassen und dieses Modul in einem Skript aufrufen (import Modulxy) und sich anschließend um den Programmablauf kümmern. Hab ich das richtig verstanden?
BlackJack

@Hakan: Eher nicht, aber das ist auch alles ein bisschen sehr abstrakt ohne konkreten Code.
Hakan
User
Beiträge: 38
Registriert: Mittwoch 8. Februar 2017, 12:13

Ich wollte nur ein Ratschlag mein Code will ich nicht teilen :-) Danke für den Versuch es mir abstrakt zu erklären!
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Wenn du zwei Prozesse startest, brauchst du zwei mal Ressourcen für die beiden Python-Interpreter.
Also wäre ein Prozess ressourcenschonender.

Sofern du nicht mit Threads arbeitest, brauchst du nicht weiter nachzudenken.

Komplex wird es erst, wenn du CPU-Intensive Berechnungen durchführen möchtest, diese am besten im Hintergrund und das verteilt auf mehre Kerne. Dann hast du gleich mehrere Probleme zu lösen.

PS: Keine Angst, deinen Code würden wir nicht gegen dich verwenden.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
oder ob ich in ein drittes Skript eine Main schreibe und durch das Modul subprocess die beiden Skripte aufrufe.
Das ist mit 99,9% Sicherheit der falsche Weg. Wenn dann wie oben gesagt importieren, ggf. Klassen instanzieren und Methoden / Funktionen aufrufen.

Wenn die Skripte so rein gar nichts miteinandern zu tun haben (z.B. eine Webanwendung und ein Skript, was die GPIOs eines Raspi steuert), dann würde ich bei Skripte unabhängig voneinander aufrufen.

BTW: keine Code zeigen wollen macht die Sache immer seeeehr verdächtig...

Gruß, noisefloor
Hakan
User
Beiträge: 38
Registriert: Mittwoch 8. Februar 2017, 12:13

Letztendlich will ich ein Autostart Skript programmieren welches je nach Zustand entweder das eine oder das andere oder beide Skripte aufruft. Die Funktionen zwischen den Skripten sind zum teil gleich zum teil anders aber die Ressourcen werden nicht geteilt!. Ich bin das ganze von Anfang an prozedural angegangen also lassen wir das Objektorientierte außen vor. Threads sind beinhaltet.

@noisefloor: Ich kenne den insider wahrscheinlich noch nicht..was war gemeint mit sehr verdächtig? :D
Hakan
User
Beiträge: 38
Registriert: Mittwoch 8. Februar 2017, 12:13

Ich hab in der Zwischenzeit mal etwas "gegoogelt" und herausgefunden wie man mehrere Aufgaben parallel asynchron laufen lassen kann (Modul: concurrent.futures). Ist das nicht cool? Python steckt voller möglichkeiten :D
BlackJack

@Hakan: Objektorientiert aussen vor lassen ist bei einer durch und durch objektorientiert aufgebauten Sprache nicht so einfach. Und vielleicht auch nicht sinnvoll. Ausser Klassen gibt es nur `collections.namedtuple` als Verbunddatentyp, oder Wörterbücher, die dann aber von der Syntax her nicht so schön sind. Und bei `collections.namedtuple` hat man die Einschränkung, das man damit nur Werttypen erstellen kann.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@Hakan: was heißt denn "Zustand" in dem Kontext? Ist das ein Wert, den du irgendwo ausliest? Oder ist das eine Uhrzeit? Davon hängt ggf. auch das "wie" der finalen Umsetzung ab...
wie man mehrere Aufgaben parallel asynchron laufen lassen kann (Modul: concurrent.futures). Ist das nicht cool? Python steckt voller möglichkeiten
Das geht auch mit dem threading-Modul oder dem multiprocessing-Modul oder dem asyncio-Modul. Basierend auf deiner bisherigen Beschreibung sehe aber nicht, was dir das bringen soll...

Gruß, noisefloor
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Hakan hat geschrieben:und herausgefunden wie man mehrere Aufgaben parallel asynchron laufen lassen kann
Das erscheint lediglich so. Wirkliche Parallelität lässt sich in Python nur mit Multiprocessing erreichen. Alles andere läuft sequentiell.
BlackJack

@kbr: Nö, das läuft echt parallel und in (fast) keinem Fall sequentiell. Du setzt hier `concurrent.futures` mit Threads gleich, was aber nur stimmt wenn man den `ThreadPoolExecutor` verwendet. Zudem gibt es das GIL nicht in jeder Python-Implementierung. Und sequentiell laufen nicht einmal Threads mit GIL bei einem Einprozessorsystem mit nur einem Kern, es sei denn es gibt dort keine Threads vom System oder die wären wirklich total Banane implementiert.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@BlackJack: ich beziehe mich hier auf CPython, also das echte mit GIL :wink:
Parallelität gibt es dort erst bei Verwendung des ProcessPoolExecutor; also Multiprocessing. Wichtig, wenn die Anwendung CPU-Bound ist. Obgleich moderne Prozessoren inzwischen so schnell sind, dass es in solchen Fällen zumeist sinnvoller ist, kompilierte Libraries einzubinden, statt weitere Python-Prozesse zu starten.
Anders sieht es bei I/O lastigen Anwendungen aus — hier können Threads und async sinnvoll zum Einsatz kommen. Jedoch wird in beiden Fällen innerhalb eines Prozesses Python-Code nicht parallel ausgeführt. Aber was erzähle ich Dir ...
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Man sollte sich den Vortag mal ansehen um zu verstehen was der GIL für komische Effekte hat: https://www.youtube.com/watch?v=Obt-vMVdM8s
Ohne den GIL wäre Python außerdem viel langsamer. Da sich hier die meisten auf die CPython Implementierung beziehen, ist die Aussage schon richtig, dass man CPU-Bound Tasks nicht in Threads einbinden sollte.

Fakt ist, dass bei der CPython Implementierung nur eine Python-Instruktion parallel ausgeführt wird. Das ändert man auch nicht mal eben.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
snafu
User
Beiträge: 6732
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Threads sind in CPython erst dann eine schlechte Idee, wenn man damit CPU-lastige Abläufe auf mehrere Kerne aufteilen will, um sie zu beschleunigen. Die laufen dann womöglich tatsächlich auf 2 Kernen, aber es bringt einem nichts, weil durch Pythons GIL trotzdem immer ein Thread warten muss bis der andere den GIL freigegeben hat. Das bedeutet nicht, dass der erste Thread erstmal komplett fertig sein muss. Es kann durchaus mehrmals pro Sekunde automatisch zwischen den Threads gewechselt werden (abhängig von der Performance des Rechners und was genau gemacht werden muss). Aber am Ende wird genau soviel Zeit verbraucht wie bei einer sequenziellen Ausführung der Aufgaben ohne Threads (aufgrund des Verwaltungsaufwands sogar etwas mehr). Wenn man Threads aber benötigt, weil z.B. der Benutzer noch etwas anderes im Programm tun darf, während eine Sounddatei läuft oder sowas, dann sind Threads eine gute Idee.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Threads bei IO stellen auch ein großes Problem dar. Ich denke kaum, dass hier jemand mal einen Server mit Threading in Python programmiert hat, der mehr als 10k Requests pro Sekunde schafft. Die Threads sind übrigens echte Threads. Jeder sollte wissen, dass auch Threads Systemressourcen verbrauchen. Prozesse benötigen noch mehr Ressourcen als Threads.

Für kleine Anwendung sind Threads geeignet. Threading fehlerfrei zu programmieren ist nochmal eine ganz andere Hausnummer. Das kann so weit gehen, dass ein Programm komplett mit Threads programmiert worden ist und am Ende stellt sich heraus, dass das komplette Programm durch die ganzen Locks Synchron abläuft.

Für die genannten Beispiele eignen sich Threads natürlich.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten