Es geht um Python 3.9 und in Python 3.10 vermutlich genauso ...
Ich wollte ermitteln, ob das "Thread" bzw neuere "Threading" Modul einen
Thread quasigleichzeitig oder tasächlich gleichzeitig ausführt.
Ich stoße in der Doku immer wieder auf die Formulierung
"In CPython, due to the Global Interpreter Lock" ....
So wie ich das verstanden habe ist Cpython ein Ding, das von Python nach
C übersetzt.
Meine Frage: Und was gilt jetzt für Python 3.9 bzw 3.10?
Hat der auch den GIL, oder ist der dortige Python - Interpreter
Thread-Safe.
Dann müßte er aber für jeden Thread einen eigene Instanz des
Interpreters mit starten ...
Kann mir jemand erleuchten ?
Danke Mario
Interessant, das war mir bisher nicht bewusst. Laut
https://towardsdatascience.com/multithreading-multiprocessing-python-180d0975ab29
:
"In fact, a Python process cannot run threads in parallel but it can run
them concurrently through context switching during I/O bound operations.
This limitation is actually enforced by GIL. The Python Global
Interpreter Lock (GIL) prevents threads within the same process to be
executed at the same time."
MarioE schrieb:> So wie ich das verstanden habe ist Cpython ein Ding, das von Python nach> C übersetzt.
Nein, CPython ist einfach die "klassische" in C implementierte Version
von Python. Siehe https://en.wikipedia.org/wiki/CPython
Da steht übrigens auch gleich:
"A particular feature of CPython is that it makes use of a global
interpreter lock (GIL) on each CPython interpreter process, which means
that within a single process, only one thread may be processing Python
bytecode at any one time."
Max schrieb:> Alternative ist multiprocessing, da scheint es zu gehen:>> https://docs.python.org/3/library/multiprocessing.html
Das erzeugt jedoch auch weitere Prozesse und nicht Threads.
Es gab schon reichlich Versuche den GIL granularer zu machen, aber einen
echten Zeitvorteil konnte man daraus nicht ableiten. Es musste halt zu
viel geprüft, gelockt und wieder freigegeben werden.
Will man echt parallel arbeiten, dann eben nur mit weiteren Prozessen.
Das übrigens kostet unter Linux deutlich weniger Zeit und Resourcen als
unter Windows. Wie es zB. beim Mac aussieht, kann ich jedoch nicht
sagen.
MarioE schrieb:> So wie ich das verstanden habe ist Cpython ein Ding, das von Python nach> C übersetzt.
Du verwechselst CPython und Cython.
> Meine Frage: Und was gilt jetzt für Python 3.9 bzw 3.10?> Hat der auch den GIL, oder ist der dortige Python - Interpreter> Thread-Safe.
Der Interpreter ist WEGEN des GIL thread-safe.
Wenn Du wirklich parallel laufenden Code schreiben, also: mehrere
CPU-Kerne nutzen möchtest, kannst Du das Standardmodul multiprocessing
benutzen, dessen Interfaces zu jenen von threading weitestgehend
kompatibel ist. Andererseits gibt es in dem Paket concurrent.futures
noch die Klassen ThreadPoolExecutor und ProcessPoolExecutor, die
außerdem Context Manager sind und daher mit dem with-Statement
ausgeführt werden können.
Einen IMHO sehr guten Artikel zu den Themen findest Du hier [1], die
Dokumentation hier [2], und ansonsten bietet "Python Module Of The Week"
[3] weitere Beispiele und Erläuterungen. Neben der offiziellen
Dokumentation sind RealPython und PyMOTW sehr empfehlenswert; die Seite
"geeksforgeeks" hat auch viel Material, erreicht meistens aber nicht die
Qualität der vorgenannten Seiten.
Für die allermeisten Aufgaben ist Python allerdings ohnehin schnell
genug, und für nicht allzu komplexe Berechnungen sind die Aufwände zur
Erzeugung, Verwaltung, und Beendigung von Threads und Prozessen größer
als jeder durch die Parallelisierung erzielte Vorteil, und das
Amdahlsche Gesetz gilt natürlich uneingeschränkt. Zudem gibt es viele
Module, zum Beispiel numpy, scipy, Pandas und weitere, die ohnehin
bereits hinter den Kulissen ein Multiprocessing betreiben und mit den in
den oben genannten Dokumentationen beschriebenen Möglichkeiten nicht
weiter beschleunigt werden können.
Je nach Aufgabe könnte es im Übrigen auch sinnvoll sein, weitere
Möglichkeiten in Erwägung zu ziehen, etwa die verteilte Task Queues wie
Celery [4], MRQ [5], RQ [6] oder Huey [7]. Damit kannst Du Deine
Aufgaben nicht nur lokal auf mehrere CPU-Kerne verteilen, sondern, wenn
vorhanden, auch die anderer Maschinen benutzen.
Ansonsten gelten natürlich die klassischen Regeln der
Performanceoptimierung auch für Python:
- "Premature optimization is the root of all evil." (Donald E. Knuth)
- "Measure, don't guess." (Kirk Pepperdine)
- "Make it work, make it right, make it fast." (Kent Beck)
Oder, um es kurz zu sagen: stell' Dir diese Fragen frühestens dann, wenn
Dein Code objektiv zu langsam ist, und fange dann damit an, zu messen,
welcher Teil des Code zu langsam ist. Vorher ist jeder Handschlag zur
Performanceoptimierung sinnlos verschenkte Zeit, und Standardrezepte
funktionieren ohnehin nie. HTH, YMMV.
[1] https://realpython.com/python-concurrency/
[2] https://docs.python.org/3/library/concurrency.html
[3] https://pymotw.com/3/py-modindex.html
[4] https://docs.celeryq.dev/en/stable/
[5] https://mrq.readthedocs.io/en/latest/
[6] https://python-rq.org/
[7] https://huey.readthedocs.io/en/latest/
Ein T. schrieb:> Für die allermeisten Aufgaben ist Python allerdings ohnehin schnell> genug,
Diese Floskel kommt beim Thema Python (und Threads) praktisch immer und
wird als heiliges Mantra akzeptiert ohne kritisch zu hinterfragen.
Sie ist gleichermaßen genau so falsch und richtig wie:
> "Premature optimization is the root of all evil." (Donald E. Knuth)
Witzig dabei, dass Knuth beinahe sein ganzes Leben dem Finden,
Analysieren und eben dem Optimieren von Algorithmen gewidmet hat.
Das obige Knuth-Zitat wird ständig missbraucht um unzulängliche
Performance zu rechtfertigen.
Letztlich findet Skalierung schon seit vielen Jahren beinahe
ausschließlich Horizontal und nicht Vertikal statt, gerade auch auf
Prozess/Thread-Ebene. Sprachen und Laufzeitsysteme die diese Realität
nicht durch robuste, performante und einfache Mechanismen den
Programmierern zur Verfügung stellen, werden langfristig an Bedeutung
verlieren.
Einer schrieb:> Sprachen und Laufzeitsysteme die diese Realität> nicht durch robuste, performante und einfache Mechanismen den> Programmierern zur Verfügung stellen, werden langfristig an Bedeutung> verlieren.
Niemand wird davon abgehalten mehrere Prozesse zu starten und einzelne
Teile seiner Python-Applikation parallel laufen zu lassen.
Wenn man nicht gerade wie ein Berserker Prozesse im Millisekunden Takt
kreiert und zerstört, sollte das wohl wirklich kein Problem sein.
Norbert schrieb:> Niemand wird davon abgehalten mehrere Prozesse zu starten und einzelne> Teile seiner Python-Applikation parallel laufen zu lassen.
Programmiersprachen für moderne Anwendungsprogrammierung sollten sich
dem Multithreading mit möglichst geringem Aufwand für den Programmierer
widmen. Einschliesslich dynamischer Ablaufmodelle statt altbackener
statischer Aufteilung.
Man sollte so programmieren, dass die ausfuehrung egal ist. Bei den
Haltepunkten wird an das Betreibsystem, resp den Kernel uebergeben. dann
kommt ein anderer Thread, unter Kernelkontrolle, und irgendwann, dh nach
der Delay zeit geht's weiter. Man sollte keine weiteren Annahmen
treffen.
(prx) A. K. schrieb:> Norbert schrieb:>> Niemand wird davon abgehalten mehrere Prozesse zu starten und einzelne>> Teile seiner Python-Applikation parallel laufen zu lassen.>> Programmiersprachen für moderne Anwendungsprogrammierung sollten sich> dem Multithreading mit möglichst geringem Aufwand für den Programmierer> widmen. Einschliesslich dynamischer Ablaufmodelle statt altbackener> statischer Aufteilung.
Jo.
Dann schmeißen wir einfach mal alle Sprachen die da nicht hinein passen
weg.
Ups, das ist aber sehr übersichtlich hier. Wo sind denn alle?
Und in der neuen Programmiersprachen schreiben wir im Klartext:
1
Tach Computer.
2
Ich hätte gerne ein Programm welches: < Hier bitte die Wünsche einsetzen>
3
4
Oh, noch etwas Computer, mach's bitte richtig schnell.
Einer schrieb:> Sprachen und Laufzeitsysteme die diese Realität> nicht durch robuste, performante und einfache Mechanismen den> Programmierern zur Verfügung stellen, werden langfristig an Bedeutung> verlieren.
Peformance ist aber nicht das einzige Merkmal das selektiert wird. Wäre
dem so gäbe es keine Scriptsprachen. Im wissenschaftlichen Bereich wo
hohe Performance gefragt ist, etwa bei Simulationen oder Deep Learning,
trifft man immer auf Python, das die Rolle einer Interface Sprache
spielt. Die Performance kritischen Komponenten sind in einer anderen
Sprache geschrieben und werden über Python konfiguriert angesteuert.
Und man kann definitiv die Beobachtung machen dass maximale Performance
und eine einfache Programmiersprache sich gegenseitig weitgehend
ausschließen.
Rust macht beispielsweise Multithreading einfacher und sicherer, aber es
ist alles andere als eine einfache Programmiersprache. Es ist daher
keine Konkurrenz für Python.
Übrigens man sollte sich nicht unbedingt auf die Standard
Implementierung CPython versteifen. PyPy kann eine Anwendung ohne Code
Änderungen bereits um das vielfache schneller machen.
Und ab einem gewissen Punkt macht es einfach keinen Sinn Python zu
nutzen wenn man jeden Funken Leistung benötigt.
Ihr müsst mir mal helfen…
Habe gerade nochmals sorgfältig den Eröffnungsbeitrag gelesen.
Konnte nirgendwo auch nur die geringste Andeutung bzgl. maximaler
Performance, anderer Programmiersprachen, usw. erkennen.
Ich habe den Text derart interpretiert, das der TE eigentlich nur
Informationen über Threading und GIL bei Python 3.viel haben wollte.
Aber vermutlich vertue ich mich auch einfach nur und erkenne das große
Ganze nicht…
Norbert schrieb:> Ihr müsst mir mal helfen…
Scheint so, ja.
> Ich habe den Text derart interpretiert, das der TE eigentlich nur> Informationen über Threading und GIL bei Python 3.viel haben wollte.
Soweit ich sehen kann, wurden alle relevanten Antworten dazu bereits
mehrfach gegeben. Fehlt dir irgendetwas?
Rolf M. schrieb:> Soweit ich sehen kann, wurden alle relevanten Antworten dazu bereits> mehrfach gegeben. Fehlt dir irgendetwas?
Ganz im Gegenteil.
Es hat den Anschein als ob nahezu jeder Thread mit unsinnigem Zeug,
welches überhaupt nicht zum Thema gehört, zugeschwurbelt wird.
Entweder sind die meisten Menschen nicht mehr in der Lage einfachste
Texte oder Fragen zu verstehen, oder es steckt der Plan dahinter dieses
Forum entweder durch schiere Blödheit oder maßlos übertriebene
Selbstdarstellung möglichst unerträglich zu machen.
Das sind übrigens gleichermaßen Gäste und ›Angemeldete‹
Zur Verifikation genügt einfach ein Vergleich der Beiträge ›fünf Jahre
zuvor‹ und ›Jetzt‹
Norbert schrieb:> Es hat den Anschein als ob nahezu jeder Thread mit unsinnigem Zeug,> welches überhaupt nicht zum Thema gehört, zugeschwurbelt wird.
[...]
> schiere Blödheit oder maßlos übertriebene Selbstdarstellung
Glashaus? Um es zu konkretisieren:
- Bis jetzt 3 Offtopic-Beiträge von Dir hier.
- Du bist der Erste mit einem polemischen Beitrag hier.
- Du bist der Erste der andere Teilnehmer der Blödheit bezichtigt.
- Du bist der Erste der einen Plan (Verschwörung) wittert.
Was kommt als nächstes?
Norbert schrieb:> Rolf M. schrieb:>> Soweit ich sehen kann, wurden alle relevanten Antworten dazu bereits>> mehrfach gegeben. Fehlt dir irgendetwas?>> Ganz im Gegenteil.
Also stört dich, dass nach der hinreichenden Beantwortung der Frage die
Kommunikation nicht sofort eingestellt wurde, sondern über damit
zusammenhängende Dinge weiter diskutiert wird?
Ich finde das eigentlich gut, denn daraus sind hier schon einige
interessante Diskussionen entstanden. Natürlich kommt es auch zu
Flamewars und anderen Störungen, aber das lässt sich nicht immer
vermeiden.
> Es hat den Anschein als ob nahezu jeder Thread mit unsinnigem Zeug,> welches überhaupt nicht zum Thema gehört, zugeschwurbelt wird.
Dir ist bewusst, dass du genau das gerade selbst tust?
> Entweder sind die meisten Menschen nicht mehr in der Lage einfachste> Texte oder Fragen zu verstehen, oder es steckt der Plan dahinter dieses> Forum entweder durch schiere Blödheit oder maßlos übertriebene> Selbstdarstellung möglichst unerträglich zu machen.
Weil man hier über Multithreading und Multiprocessing in Python und
anderen Sprachen diskutiert?
Einer schrieb:> Ein T. schrieb:>> Für die allermeisten Aufgaben ist Python allerdings ohnehin schnell>> genug,>> Diese Floskel kommt beim Thema Python (und Threads) praktisch immer
Ja, aber es ist keine Floskel, sondern eine Aussage, und die kommt so
oft, weil sie schlicht und einfach stimmt.
> und> wird als heiliges Mantra akzeptiert ohne kritisch zu hinterfragen.
Nö, die Aussage ist einfach nur vollkommen richtig.
Performanceoptimierung ist kein Selbstzweck (okay, außer vielleicht für
Dich).
> Sie ist gleichermaßen genau so falsch und richtig wie:>>> "Premature optimization is the root of all evil." (Donald E. Knuth)>> Witzig dabei, dass Knuth beinahe sein ganzes Leben dem Finden,> Analysieren und eben dem Optimieren von Algorithmen gewidmet hat.
Wie gesagt: Performanceoptimierung ist kein Selbstzweck. So etwas macht
man nur dann, wenn es notwendig ist -- und diese Fälle sind insbesondere
außerhalb der Mikrocontroller-Welt nun einmal sehr, sehr selten. Die
meisten Programme in der realen Welt machen einen Großteil ihrer
Laufzeit lang ohnehin nichts anderes, als auf die Eingaben eines
Benutzers oder auf den I/O zu warten.
Wie Du übrigens sehr richtig erkannt hast, hat Knuth sein Leben übrigens
nicht der Optimierung von Programmen, sondern der Optimierung von
Algorithmen gewidmet. Das ist ein riesiger Unterschied, und deswegen
auch kein Widerspruch zum Zitat.
> Das obige Knuth-Zitat wird ständig missbraucht um unzulängliche> Performance zu rechtfertigen.
Von Dir vielleicht. Sonst kenne ich niemanden, der das tut.
> Letztlich findet Skalierung schon seit vielen Jahren beinahe> ausschließlich Horizontal und nicht Vertikal statt, gerade auch auf> Prozess/Thread-Ebene. Sprachen und Laufzeitsysteme die diese Realität> nicht durch robuste, performante und einfache Mechanismen den> Programmierern zur Verfügung stellen, werden langfristig an Bedeutung> verlieren.
Das ist zwar nur teilweise richtig, aber sei's drum. Zudem hat Python
Mechanismen dafür, in vielen verschiedenen Geschmäckern, und sie alle
sind robust, performant und einfach. Wo ist Dein Problem?
Ein T. schrieb:> Einer schrieb:>> Ein T. schrieb:>>> Für die allermeisten Aufgaben ist Python allerdings ohnehin schnell>>> genug,>>>> Diese Floskel kommt beim Thema Python (und Threads) praktisch immer>> Ja, aber es ist keine Floskel, sondern eine Aussage, und die kommt so> oft, weil sie schlicht und einfach stimmt.>>> und>> wird als heiliges Mantra akzeptiert ohne kritisch zu hinterfragen.>> Nö, die Aussage ist einfach nur vollkommen richtig.
Dein "vollkommen" ist ziemlich stark abhängig von deiner Definition von
"allermeisten" und "schnell genug". Bei mir ist Python für die
allermeisten Aufgaben nicht schnell genug.
Ein T. schrieb:>> Letztlich findet Skalierung schon seit vielen Jahren beinahe>> ausschließlich Horizontal und nicht Vertikal statt, gerade auch auf>> Prozess/Thread-Ebene. Sprachen und Laufzeitsysteme die diese Realität>> nicht durch robuste, performante und einfache Mechanismen den>> Programmierern zur Verfügung stellen, werden langfristig an Bedeutung>> verlieren.>> Das ist zwar nur teilweise richtig, aber sei's drum. Zudem hat Python> Mechanismen dafür, in vielen verschiedenen Geschmäckern, und sie alle> sind robust, performant und einfach. Wo ist Dein Problem?
Was sind denn diese robusten performanten und einfachen Mechanismen?
mh schrieb:> Dein "vollkommen" ist ziemlich stark abhängig von deiner Definition von> "allermeisten" und "schnell genug". Bei mir ist Python für die> allermeisten Aufgaben nicht schnell genug.
Da mir Deine Aufgaben unbekannt sind, kann und will ich diese Aussage
nicht beurteilen.
> Ein T. schrieb:>> Das ist zwar nur teilweise richtig, aber sei's drum. Zudem hat Python>> Mechanismen dafür, in vielen verschiedenen Geschmäckern, und sie alle>> sind robust, performant und einfach. Wo ist Dein Problem?>> Was sind denn diese robusten performanten und einfachen Mechanismen?
Die Module threading und multiprocessing zum Beispiel, die nicht ganz
von ungefähr weitestgehend kompatible APIs bieten und daher austauschbar
sind. Zudem das Modul concurrent.futures mit ThreadPoolExecutor und
ProcessPoolExecutor. Asynchrone Programmierung mit Callbacks geht
natürlich auch. Das alles gehört schon zum ganz normalen Standardumfang
von Python.
Zudem gibt es eine Reihe externer Module, mit denen Du nicht nur lokale,
sondern auch externe Rechenpower nutzen kannst, etwa Celery und Joblib
oder, wenn es ein bisschen "klassischer" sein soll, mpi4py. Weitere
Links findest Du hier: [1].
Obendrein gibt es eine Reihe von Modulen, wie etwa numpy oder Module aus
dem scikit-Universum, die ihrerseits in C oder C++ geschrieben sind und
sich ihrerseits ohne irgendein Zutun des Entwicklers um die
Parallelisierung kümmern.
Du siehst: alles ist vorhanden und kann ganz einfach genutzt werden.
Hast Du noch weitere Fragen an mich, die Du Dir mit der Suchmaschine
Deines geringsten Mißtrauens in wenigen Sekunden selbst beantworten
könntest?
[1] https://wiki.python.org/moin/ParallelProcessing
Ein T. schrieb:> mh schrieb:>> Dein "vollkommen" ist ziemlich stark abhängig von deiner Definition von>> "allermeisten" und "schnell genug". Bei mir ist Python für die>> allermeisten Aufgaben nicht schnell genug.>> Da mir Deine Aufgaben unbekannt sind, kann und will ich diese Aussage> nicht beurteilen.
Dann solltest du vielleicht etwas weniger absolute Aussagen treffen.
>> Ein T. schrieb:>>> Das ist zwar nur teilweise richtig, aber sei's drum. Zudem hat Python>>> Mechanismen dafür, in vielen verschiedenen Geschmäckern, und sie alle>>> sind robust, performant und einfach. Wo ist Dein Problem?>>>> Was sind denn diese robusten performanten und einfachen Mechanismen?>> Die Module threading und multiprocessing zum Beispiel, die nicht ganz> von ungefähr weitestgehend kompatible APIs bieten und daher austauschbar> sind. Zudem das Modul concurrent.futures mit ThreadPoolExecutor und> ProcessPoolExecutor. Asynchrone Programmierung mit Callbacks geht> natürlich auch. Das alles gehört schon zum ganz normalen Standardumfang> von Python.
Threads fallen schonmal für fast alle meiner Anwendungsfälle weg, da sie
dank GIL keinen Vorteil bringen. Das gleiche gilt für asynchrone
Programmierung. Dann bleiben nur noch Prozesse übrig und die fallen für
mich nicht unter "robust, performant und einfach".
> Zudem gibt es eine Reihe externer Module, mit denen Du nicht nur lokale,> sondern auch externe Rechenpower nutzen kannst, etwa Celery und Joblib> oder, wenn es ein bisschen "klassischer" sein soll, mpi4py. Weitere> Links findest Du hier: [1].
Also sind wir bei der guten alten "Jobverwaltung" angekommen. Dann kann
ich auch gleich slurm benutzen ;-)
> Obendrein gibt es eine Reihe von Modulen, wie etwa numpy oder Module aus> dem scikit-Universum, die ihrerseits in C oder C++ geschrieben sind und> sich ihrerseits ohne irgendein Zutun des Entwicklers um die> Parallelisierung kümmern.
Die Module kümmern sich um die Parallelisierung, wenn man die passenden
Probleme hat. Da können kleine Abweichungen ganz schnell zum
Performance-Killer werden.
> Du siehst: alles ist vorhanden und kann ganz einfach genutzt werden.> Hast Du noch weitere Fragen an mich, die Du Dir mit der Suchmaschine> Deines geringsten Mißtrauens in wenigen Sekunden selbst beantworten> könntest?>> [1] https://wiki.python.org/moin/ParallelProcessing
Und nichts von dem was du aufgelistet hast ist robust, einfach und
performant. Alles nur ... Floskeln ...
Ein T. schrieb:> Einer schrieb:>> Ein T. schrieb:>>> Für die allermeisten Aufgaben ist Python allerdings ohnehin schnell>>> genug,>>>> Diese Floskel kommt beim Thema Python (und Threads) praktisch immer>> Ja, aber es ist keine Floskel, sondern eine Aussage, und die kommt so> oft, weil sie schlicht und einfach stimmt.
mh schrieb:> Ein T. schrieb:>> Die Module threading und multiprocessing zum Beispiel, die nicht ganz>> von ungefähr weitestgehend kompatible APIs bieten und daher austauschbar>> sind. Zudem das Modul concurrent.futures mit ThreadPoolExecutor und>> ProcessPoolExecutor. Asynchrone Programmierung mit Callbacks geht>> natürlich auch. Das alles gehört schon zum ganz normalen Standardumfang>> von Python.> Threads fallen schonmal für fast alle meiner Anwendungsfälle weg, da sie> dank GIL keinen Vorteil bringen. Das gleiche gilt für asynchrone> Programmierung. Dann bleiben nur noch Prozesse übrig und die fallen für> mich nicht unter "robust, performant und einfach".
Einerseits sagst Du natürlich nichts zu Deinen hochgeheimen
Anwendungsfällen, die so unglaublich performant sein müssen, während Du
andererseits stabile, getestete und in Millionen Anwendungen verwendete
Standardmodule wie multiprocessing einfach mal ohne jedwede Begründung
und ohne jedes Sachargument als nicht genügend "robust, performant und
einfach" abtust.
> Und nichts von dem was du aufgelistet hast ist robust, einfach und> performant. Alles nur ... Floskeln ...
Bisher lese ich nur von Dir Floskeln. Offenbar willst Du nicht
diskutieren und auch nichts dazu lernen, sondern nur trollen. Das wäre
ja nicht einmal schlimm, wenn Du dabei wenigstens ein bisschen originell
oder gar witzig wärst. Aber so?
Karl Käfer schrieb:> mh schrieb:>> Ein T. schrieb:>>> Die Module threading und multiprocessing zum Beispiel, die nicht ganz>>> von ungefähr weitestgehend kompatible APIs bieten und daher austauschbar>>> sind. Zudem das Modul concurrent.futures mit ThreadPoolExecutor und>>> ProcessPoolExecutor. Asynchrone Programmierung mit Callbacks geht>>> natürlich auch. Das alles gehört schon zum ganz normalen Standardumfang>>> von Python.>> Threads fallen schonmal für fast alle meiner Anwendungsfälle weg, da sie>> dank GIL keinen Vorteil bringen. Das gleiche gilt für asynchrone>> Programmierung. Dann bleiben nur noch Prozesse übrig und die fallen für>> mich nicht unter "robust, performant und einfach".>> Einerseits sagst Du natürlich nichts zu Deinen hochgeheimen> Anwendungsfällen, die so unglaublich performant sein müssen, während Du> andererseits stabile, getestete und in Millionen Anwendungen verwendete> Standardmodule wie multiprocessing einfach mal ohne jedwede Begründung> und ohne jedes Sachargument als nicht genügend "robust, performant und> einfach" abtust.
Wenn multiporocessing so stabil und getestet ist, sollte man sowas:
1
Exception in thread Thread-1:
2
Traceback (most recent call last):
3
File ".../lib/python3.7/threading.py", line 926, in _bootstrap_inner
4
self.run()
5
File ".../lib/python3.7/threading.py", line 870, in run
6
self._target(*self._args, **self._kwargs)
7
File "foo.py", line 198, in run
8
baa(nodeId, job, p.exitcode == 0)
9
File ".../lib/python3.7/multiprocessing/managers.py", line 724, in temp
10
token, exp = self._create(typeid, *args, **kwds)
11
File ".../lib/python3.7/multiprocessing/managers.py", line 609, in _create
File ".../lib/python3.7/multiprocessing/managers.py", line 201, in handle_request
19
result = func(c, *args, **kwds)
20
File ".../lib/python3.7/multiprocessing/managers.py", line 407, in create
21
self.incref(c, ident)
22
File ".../lib/python3.7/multiprocessing/managers.py", line 440, in incref
23
raise ke
24
File ".../lib/python3.7/multiprocessing/managers.py", line 427, in incref
25
self.id_to_refcount[ident] += 1
26
KeyError: '55413bf1bf71'
als Nutzer eigentlich nicht zu sehen bekommen, oder? Ein "KeyError"
irgendwo in einem Thread der von Python im Hintergrund erzeugt wurde und
von Python gemanagt wird. Kein Hinweis darauf was schief gelaufen ist.
Kein Hinweis in der Doku, wie man mit diesem Fehler umgehen soll. Und
natürlich nicht reproduzierbar. Damit fällt multiprocessing für mich
nicht mehr unter "robust und einfach".
mh schrieb:> als Nutzer eigentlich nicht zu sehen bekommen, oder? Ein "KeyError"> irgendwo in einem Thread der von Python im Hintergrund erzeugt wurde und> von Python gemanagt wird. Kein Hinweis darauf was schief gelaufen ist.
Steht doch da, Zeile 198 in der Datei "foo.py".
> Kein Hinweis in der Doku, wie man mit diesem Fehler umgehen soll. Und> natürlich nicht reproduzierbar. Damit fällt multiprocessing für mich> nicht mehr unter "robust und einfach".
Da hast Du offenbar etwas kaputt gemacht und behauptest jetzt, Python
sei schuld. Anscheinend hatte "Karl Käfer" Recht.
Ein T. schrieb:> mh schrieb:>> als Nutzer eigentlich nicht zu sehen bekommen, oder? Ein "KeyError">> irgendwo in einem Thread der von Python im Hintergrund erzeugt wurde und>> von Python gemanagt wird. Kein Hinweis darauf was schief gelaufen ist.>> Steht doch da, Zeile 198 in der Datei "foo.py".
Nur passiert da nichts mit multiprocessing/manager.py. Das einzige was
dort mit multiprocessing zu tun hat ist p. Das ist ein
multiprocessing.Process. Kannst du mir jetzt erklären was das soll?
>> Kein Hinweis in der Doku, wie man mit diesem Fehler umgehen soll. Und>> natürlich nicht reproduzierbar. Damit fällt multiprocessing für mich>> nicht mehr unter "robust und einfach".>> Da hast Du offenbar etwas kaputt gemacht und behauptest jetzt, Python> sei schuld. Anscheinend hatte "Karl Käfer" Recht.
Du kannst mir jetzt sicherlich die Stelle in der Python Dokumentation
zeigen, die mir verbietet den exitcode eines multiprocess.Process
abzufragen, oder wenigstens unter welchen Umständen dabei welche
Exception geworfen wird.
Ich sage nicht, dass ich nichts falsch mache. Aber solange du, oder KK,
mir nicht sagen kannst was dieser Fehler zu bedeuten hat, zweifle ich
das "einfach und robust" an.
mh schrieb:> Du kannst mir jetzt sicherlich die Stelle in der Python Dokumentation> zeigen, die mir verbietet den exitcode eines multiprocess.Process> abzufragen, oder wenigstens unter welchen Umständen dabei welche> Exception geworfen wird.
Es gibt keine solche Stelle, denn man kann und darf natürlich den
exitcode eines multiprocessing.Process abfragen. Wie das geht, steht in
der Dokumentation.
> Ich sage nicht, dass ich nichts falsch mache. Aber solange du, oder KK,> mir nicht sagen kannst was dieser Fehler zu bedeuten hat, zweifle ich> das "einfach und robust" an.
Offensichtlich wollen dort mehrere Prozesse auf ein Objekt zuzugreifen,
das in den Prozessen aber natürlich nicht dasselbe Objekt ist.
Ein T. schrieb:>> Ich sage nicht, dass ich nichts falsch mache. Aber solange du, oder KK,>> mir nicht sagen kannst was dieser Fehler zu bedeuten hat, zweifle ich>> das "einfach und robust" an.>> Offensichtlich wollen dort mehrere Prozesse auf ein Objekt zuzugreifen,> das in den Prozessen aber natürlich nicht dasselbe Objekt ist.
Das ist offensichtlich? Welche Prozesse und welches Objekt denn? Ich
gebe dir etwas mehr Infos zu dem Teil der nichtssagenden Exceptions,
über den ich etwas weiß.
1
baa(nodeId,job,p.exitcode==0)
baa ist eine Funktion, nodeId ist ein int, job ist ein Tupel aus int und
string, p ist ein multiprocess.Process. Nichts davon sollte irgendwie
geteilt werden. In dem Prozess wird etwas mit anderen Prozessen über
einen multiprocess.manager geteilt. Aber da werden alle Exceptions
aufgefangen und geloggt und das Log zeigt keine Exceptions die in den
Prozessen geworfen wurden.
mh schrieb:> Das ist offensichtlich? Welche Prozesse und welches Objekt denn? Ich> gebe dir etwas mehr Infos zu dem Teil der nichtssagenden Exceptions,> über den ich etwas weiß.>
1
>baa(nodeId,job,p.exitcode==0)
2
>
> baa ist eine Funktion
Ach. Das stand schon in der Exception. Lesen bildet.
> Aber da werden alle Exceptions> aufgefangen und geloggt und das Log zeigt keine Exceptions die in den> Prozessen geworfen wurden.
Doch, tut es. Du mußt sie halt lesen, ne. Huch.
Karl Käfer schrieb:>> Aber da werden alle Exceptions>> aufgefangen und geloggt und das Log zeigt keine Exceptions die in den>> Prozessen geworfen wurden.> Doch, tut es. Du mußt sie halt lesen, ne. Huch.
Kannst du bitte genauer ausführen wo ich im Log nachlesen muss? Du
scheinst meine Logs ja besser zu kennen als ich.
mh schrieb:> Ein T. schrieb:>> Offensichtlich wollen dort mehrere Prozesse auf ein Objekt zuzugreifen,>> das in den Prozessen aber natürlich nicht dasselbe Objekt ist.> Das ist offensichtlich? Welche Prozesse und welches Objekt denn? Ich
Der Prozeß, der Deine Funktion aufruft.
> gebe dir etwas mehr Infos zu dem Teil der nichtssagenden Exceptions,> über den ich etwas weiß.
Die wichtige Info wäre der Code, der die Exceptions wirft.
Ein T. schrieb:> mh schrieb:>> Ein T. schrieb:>>> Offensichtlich wollen dort mehrere Prozesse auf ein Objekt zuzugreifen,>>> das in den Prozessen aber natürlich nicht dasselbe Objekt ist.>> Das ist offensichtlich? Welche Prozesse und welches Objekt denn? Ich>> Der Prozeß, der Deine Funktion aufruft.
Welchen Prozess meinst du? Werd mal etwas konkreter. In den Prozessen,
die ich starte (p und seine Geschwister) werden keine Exceptions
geworfen, es denn sie schaffen es unbemerkt an einem "except:" vorbei zu
kommen. In dem Traceback den ich gezeigt habe taucht der Inhalt meiner
Prozesse auch nicht auf. Es wird nur der exitcode getestet, was laut
Doku legal ist.
Ein T. schrieb:>> gebe dir etwas mehr Infos zu dem Teil der nichtssagenden Exceptions,>> über den ich etwas weiß.>> Die wichtige Info wäre der Code, der die Exceptions wirft.
Was willst du denn noch wissen außer
mh schrieb:> Ich> gebe dir etwas mehr Infos zu dem Teil der nichtssagenden Exceptions,> über den ich etwas weiß.baa(nodeId, job, p.exitcode == 0)> baa ist eine Funktion, nodeId ist ein int, job ist ein Tupel aus int und> string, p ist ein multiprocess.Process.
Mehr kann ich dir nicht geben. Mehr taucht auch nicht in dem Traceback
auf.
Norbert schrieb:> Schon komisch, bei mir läuft es. Aber vermutlich mache ich etwas falsch.
Das Totschlagargument ;-). Ein Beispiel, das nicht viel mit dem
tatsächlichen Problem zu tun hat, läuft unter Testbedingungen auf einem
komplett anderen System.
mh schrieb:> Das Totschlagargument ;-). Ein Beispiel, das nicht viel mit dem> tatsächlichen Problem zu tun hat, läuft unter Testbedingungen auf einem> komplett anderen System.
Ernsthaft jetzt?
Brauchst du es vorgekaut?
In kleinen handlichen Häppchen?
Dann solltest du besser nicht weiter versuchen parallel zu denken und zu
programmieren!
Norbert schrieb:> mh schrieb:>> Das Totschlagargument ;-). Ein Beispiel, das nicht viel mit dem>> tatsächlichen Problem zu tun hat, läuft unter Testbedingungen auf einem>> komplett anderen System.>> Ernsthaft jetzt?> Brauchst du es vorgekaut?> In kleinen handlichen Häppchen?> Dann solltest du besser nicht weiter versuchen parallel zu denken und zu> programmieren!
Was willst du sagen? Ich verstehe dich nicht. Keins deiner Beispiele hat
etwas mit der tatsächlichen Situation zu tun. Kannst du vielleicht mit
deinem "falsch" Beispiel den Traceback reproduzieren?
Norbert schrieb:> VIELLEICHT PROBIERST DU ES JA EINFACH MAL AUS.> Dann bekommst du dein Traceback. Und den KeyError.
Es gibt eine Traceback mit einem KeyError.
Dein Beispiel hat trotzdem nicht wirklich etwas mit dem tatsächlichen
Problem zu tun. Das sieht eher so aus:
Poste etwas Python Code das deinen Fehler zeigt und nachvollzogen werden
kann. Und nicht irgend ein Pseudogelumpe.
Oder glaubst du allen Ernstes das wir hier sind um dir die Infos einzeln
aus der Nase zu ziehen?
Unfassbar.
Norbert schrieb:> Poste etwas Python Code das deinen Fehler zeigt und nachvollzogen werden> kann. Und nicht irgend ein Pseudogelumpe.> Oder glaubst du allen Ernstes das wir hier sind um dir die Infos einzeln> aus der Nase zu ziehen?> Unfassbar.
Kann ich nicht, darf ich nicht, will ich nicht. Aber in meinem Beispiel
ist alles drin, um sagen zu können wo die Exception her kommt. Und dran
denken, es gibt keine "nay"s in den Logs und weder testfunction noch
make_a_manager_get_data_and_torture_the_cpu_for_200h tauchen im
Traceback auf.
mh schrieb:> Kann ich nicht, darf ich nicht, will ich nicht. Aber in meinem Beispiel> ist alles drin, um sagen zu können wo die Exception her kommt. Und dran> denken, es gibt keine "nay"s in den Logs und weder testfunction noch> make_a_manager_get_data_and_torture_the_cpu_for_200h tauchen im> Traceback auf.
Aha, geheime Software, geheime Fehler. Dann weiterhin viel Spaß!
Deine Exception kommt daher, das man einem Prozess nicht einfach den
Teppich unter den Füßen wegzieht (auch nicht die Variablen)
Und damit bin ich dann auch raus, es beginnt langweilig zu werden.
Alle diejenigen welche vernünftiges Multiprozessing machen wollen,
können sich ja an funktionsfähigem Code orientieren.
mh schrieb:> Norbert schrieb:>> Poste etwas Python Code das deinen Fehler zeigt und nachvollzogen werden>> kann. Und nicht irgend ein Pseudogelumpe.>> Kann ich nicht, darf ich nicht, will ich nicht.
Das war schon früher mein Eindruck: Du willst nicht. Danke für die
Bestätigung, anscheinend kann ich mich noch auf meine Instinkte
verlassen.
> Aber in meinem Beispiel> ist alles drin, um sagen zu können wo die Exception her kommt.
Nö. Dein Fehler ist nämlich nicht in dem Traceback, sondern in dem Code,
den Du verheimlichst, zu dem der Traceback aber inhärent und untrennbar
dazugehört.
Was Dein Beispiel hingegen sehr schön demonstriert, ist, daß Du Dich
nicht an die üblichen Konventionen hälst. Das ist nicht zwangsläufig
schlimm, aber es deutet zumindest auf einen nachlässigen Programmierstil
hin.
> Und dran> denken, es gibt keine "nay"s in den Logs und weder testfunction noch> make_a_manager_get_data_and_torture_the_cpu_for_200h tauchen im> Traceback auf.
Ein Traceback ist nicht dazu da, Dir Dein gepudertes Popöchen
nachzutragen, sondern Dir zu zeigen, wo der Fehler auftritt und wie es
dazu kam. Ohne Deinen Code, welcher den Fehler enthält, ist der
Traceback daher sinn- und wertlos.
Es gilt also weiterhin: Pythons Module für multithreading und
multiprocessing sind robust, performant, einfach, vielfach getestet,
vielfach genutzt, und stabil. Daß Du es trotzdem geschafft hast, etwas
kaputt zu machen, spricht nicht dagegen.