🐍 · Python: NebenlĂ€ufigkeit

Wenn man ein Programm schreiben möchte, das mehrere Dinge gleichzeitig tun können soll, dann stĂ¶ĂŸt man frĂŒher oder spĂ€ter auf das Konzept der NebenlĂ€ufigkeit. Ich werde mich in diesem Guide auf Python und speziell asyncio beschrĂ€nken, da das gesamte Thema gar nicht in einem einzigen Post erklĂ€rt werden könnte! NebenlĂ€ufigkeit vs. Parallelismus Zu Beginn sollte ich vielleicht den Begriff nochmal etwas genauer einschrĂ€nken: Wenn ein Programm mehrere Prozessoren (oder Prozessorkerne) fĂŒr die AusfĂŒhrung von verschiedenen Dingen benutzt, dann spricht man von paralleler Verarbeitung. Das Programm kann wirklich mehrere Dinge gleichzeitig und völlig unabhĂ€ngig voneinander tun. Mit der NebenlĂ€ufigkeit, um die es in diesem Guide gehen soll, bezeichnet man Programme, die auf einem einzigen Prozessor laufen (der also nur eine Anweisung auf einmal ausfĂŒhren kann) und scheinbar gleichzeitig verschiedene Dinge tun. In Wirklichkeit wechseln sich die Prozesse immer wieder ab und erzeugen dadurch den Eindruck der Gleichzeitigkeit.
19 Replies
Laqco
LaqcoOP‱16mo ago
asyncio und kooperatives Multitasking asyncio ist eine Python Bibiliothek, die NebenlĂ€ufigkeit in Form von kooperativem Multitasking ermöglicht. Das bedeutet, dass nicht das Betriebssystem bzw. ein Event Scheduler entscheidet, wann welcher Prozess laufen darf, sondern dass die Prozesse von sich aus die CPU "freigeben". In asyncio wird das ĂŒber das SchlĂŒsselwort await gelöst: Sobald eine Funktion mit await aufgerufen wird, hat ein anderer Prozess (aus der asyncio Event Loop) die Möglichkeit zu laufen, bis er selber wieder eine Funktion mit await aufruft. In der Regel sind diese Funktionen solche, die (verhĂ€ltnismĂ€ĂŸig fĂŒr einen Prozessor) lange auf eine "Antwort" warten mĂŒssen, wie beispielsweise Netzwerk- oder Speicherzugriffe. Sobald die Antwort da ist, können die Prozesse wieder den Prozessor "bekommen" und weiterlaufen. Das zweite wichtige SchlĂŒsselwort von asyncio ist async: Dieses steht vor allen Funktionsdefinitionen, die in irgendeiner Form await benutzen möchten, oder vor bestimmten Python-SchlĂŒsselwörtern wie with oder for (die nĂ€mlich ansonsten das "Freigeben" durch await-Aufrufe verhindern könnten). Besonderheiten bei der Programmierung mit asyncio Um die NebenlĂ€ufigkeit möglichst effektiv zu machen, muss man ein paar Sachen bei der Entwicklung von Programmen mit asyncio beachten. Zum Teil muss man andere Bibiliotheken als gewöhnlich benutzen, die zwar dieselbe FunktionalitĂ€t haben, aber mit NebenlĂ€ufigkeit. Das ist beispielsweise so bei aiohttp und aiomysql. Viele beliebte Bibiliotheken haben asyncio aber inzwischen auch schon direkt enthalten; Beispiele dafĂŒr sind Django und websockets. Weiterhin muss das Programm gĂ€nzlich gut (bzw. "kooperierend" via await) geschrieben sein, damit die NebenlĂ€ufigkeit funktioniert. Da die Event Loop keine Möglichkeit hat einen Prozess frĂŒher zu beenden, kann sich ein Programm durch kleine Fehler schnell schon aufhĂ€ngen. Zu guter Letzt: Bei rechenintensiven Prozessen ist asyncio keine gute Lösung, da es keine "Antworten" gibt, auf die gewartet werden kann. TatsĂ€chlich verlangsamt sich die ProgrammausfĂŒhrung in diesem Fall sogar, da das wechseln zwischen den Prozessen zusĂ€tzliche Zeit verbraucht. -- Feedback, Fragen und Kommentare gerne in den Post hierrunter schreiben! :) Idee: @Fabio3323 (ich hoffe, du meintest asyncio mit deinem Vorschlag xD) Quellen: - https://realpython.com/python-concurrency/ - https://en.wikipedia.org/wiki/Concurrency_(computer_science) - https://en.wikipedia.org/wiki/Computer_multitasking - https://docs.python.org/3/library/asyncio.html - https://stackoverflow.com/questions/49005651/how-does-asyncio-actually-work/51116910#51116910 - https://realpython.com/python-async-features/ - https://stackoverflow.com/questions/67092070/why-do-we-need-async-for-and-async-with - https://github.com/timofurrer/awesome-asyncio (Als nĂ€chstes plane ich aktuell den Unterschied zwischen discord.py und py-cord zu beschreiben. Allerdings wird die Recherche fĂŒr diesen Guide deutlich lĂ€nger dauern und ich muss dafĂŒr zuerst die Zeit finden ^^)
Fabio3323
Fabio3323‱16mo ago
Ich meine async Loops
Laqco
LaqcoOP‱16mo ago
Oh whoops xD Ich denke mal du meinst auch nicht die async for Loops, sondern nebenlÀufige Aufgaben innerhalb von Loops. Also mit gather oder Tasks etc. Stimmt das diesmal? xD Bevor ich wieder das Falsche beschreibe... Ich werds dann einfach direkt unter den Rest vom Post schreiben, gehört ja auch noch zum Thema
Fabio3323
Fabio3323‱16mo ago
Yes. Warte ich schick dir ein code example: async def funktion(bot, ..., when: datetime.datetime):
Laqco
LaqcoOP‱16mo ago
wo ist der code? xD
Fabio3323
Fabio3323‱16mo ago
Dieses async def Funktion und dann halt mit diesem when
Laqco
LaqcoOP‱16mo ago
aber was daran hat mit loops zu tun? das versteh ich nicht ich sehe nur eine async definierte funktion, die ein argument namens "when" hat ich werd die erklÀrung aber noch schreiben, sobald ich die zeit finde
Fabio3323
Fabio3323‱16mo ago
Jop
Martin B. ツ
Martin B. ツ‱16mo ago
Das wĂ€ren eher Scheduler die etwas zu einem bestimmten Zeitpunkt ausfĂŒhren aber keine Loops. Bissl falsch dargestellt. Sowas wie apscheduler oder aioscheduler.
Fabio3323
Fabio3323‱16mo ago
Sicher?
Martin B. ツ
Martin B. ツ‱16mo ago
naja wozu sollte man sonst when (wann) angeben? MĂŒsstest du dem @Laqco schon genauer erklĂ€ren was du meinst.
Fabio3323
Fabio3323‱16mo ago
Ich weiß es selber nicht genau. Ein Kollege hat mir das erklĂ€rt aber mehr verstehe ich auch nicht :HAhaa: https://discord.com/channels/725390391309893722/1104474089801920562
Martin B. ツ
Martin B. ツ‱16mo ago
Dann poste besser so nen code, wenn du ihn nicht verstehst. Dann kannste es anderen ja auch nicht genauer erklÀren? :Thonk: macht wenig sinn xD
Fabio3323
Fabio3323‱16mo ago
Das meine ich
Martin B. ツ
Martin B. ツ‱16mo ago
https://i.ibb.co/BgwJYDF/image.png Damit Laqco das auch nachverfolgen kann, der ist ja nicht auf dem Server. Wolltest ja eigentlich von Ihm ne ErklĂ€rung. Also das ist eher das task feature von asyncio. Das man mit einem Loop ĂŒber alle daten der db geht, um daten xy abzufragen fĂŒr bot neustart ist ja irgendwie logisch. irgendwoher mĂŒssen die daten ja kommen
Laqco
LaqcoOP‱16mo ago
(lol ich wusste nicht dass es temporĂ€re server joins gibt fĂŒr sowas, das ist ja mal ein nices feature!) soweit ich das grad sehe ist das nur eine random funktion, die nichts mit asyncio zu tun hat. das eigentliche thema sind ja tasks ich werde einen nachtrag zu tasks schreiben hatte ich ja hier schon vermutet
Fabio3323
Fabio3323‱16mo ago
Okok
Laqco
LaqcoOP‱13mo ago
aber danke @Martin B. ツ fĂŒr die aufklĂ€rung xD ich war mir tatsĂ€chlich bis jetzt nicht ganz sicher Wow, ich finde mal wieder etwas Zeit đŸ€Ż - jetzt muss ich auch mein altes Versprechen einhalten... Mit asyncio.gather kannst du mehrere coroutines (async Funktionen) "asynchron" (pun intended) ausfĂŒhren lassen und alle "Ergebnisse" (z.B. return-Werte) in einem Tupel gesammelt zurĂŒck bekommen. Intern erzeugt das fĂŒr coroutines nur einen Task und hat keine (wichtige) weitere FunktionalitĂ€t. Coroutines kann man nicht wie normale Funktionen einfach ausfĂŒhren. Stattdessen muss man sie in einer event loop "anmelden". - Die einfache Methode (außer await) ist asyncio.run(): Die coroutine wird der event loop hinzugefĂŒgt und dann ein Mal ausgefĂŒhrt. - Man kann auch mit asyncio.create_task() einen Task erstellen, der die coroutine ausfĂŒhrt. Einen Task kann man starten, stoppen, fortsetzen, auch wiederholt starten; man kann Tasks gruppieren, sie unter einem bestimmten Kontext ausfĂŒhren. Der Hauptvorteil liegt dabei vermutlich auf dem ersten Punkt: Man kann nĂ€mlich mehrere Tasks nacheinander starten (einfach das Objekt awaiten: await task; oder gather benutzen), die dann nebenlĂ€ufig ausgefĂŒhrt werden. Quellen: - https://docs.python.org/3/library/asyncio-task.html ich weiß, es ist spĂ€t, aber besser spĂ€t als nie 😅
Fabio3323
Fabio3323‱13mo ago
Huch haha

Did you find this page helpful?