[Python] Erfahren Sie mehr über asynchrone Programmierung und Ereignisschleifen

Über diesen Artikel

Um ehrlich zu sein, kann ich nicht wirklich über "Was ist asynchrone Programmierung" sprechen. Dieser Artikel beschreibt, was wir über eines der Elemente der asynchronen Programmierung gelernt haben: kollaboratives Multitasking, Pythons "Async" und Ereignisschleifen.

Kollaboratives Multitasking und asynchrone E / A.

Kollaboratives Multitasking ist ein zentrales Element der asynchronen Programmierung und wie eine Idee.

Wenn ein Computer Multitasking ausführt, wird der Kontextschalter des Betriebssystems nicht verwendet. Wenn jeder Prozess in den Standby-Zustand wechselt, gibt der Prozess selbst freiwillig die Kontrolle frei. Ermöglicht die Kontrolle vieler anderer Prozesse, die gleichzeitig ausgeführt werden. (Vergleichbar mit der Bedeutung von ** Genossenschaft **) Kontrolle bezieht sich hier auf das Anhalten und Fortsetzen eines Prozesses sowie das Zuweisen und Freigeben von Ressourcen.

Es scheint, dass alle Prozesse koordiniert werden müssen, um Multitasking reibungslos durchzuführen.

Für kollaboratives Multitasking auf Anwendungsebene

Wo machst du kollaboratives Multitasking? Anstatt mehrere Prozesse oder Threads zu koordinieren ** Alle Multitasking-Aktionen werden in einem Prozess oder Thread ausgeführt. ** ** **

Wer kontrolliert die Aufgabe? Die Steuerung mehrerer Aufgaben ist auf eine Funktion beschränkt, die die Koordination der Aufgaben verwaltet.

Schlüsselthemen beim kollaborativen Multitasking

Beim kollaborativen Multitasking ist der Zeitpunkt für die Freigabe der Kontrolle ** das wichtigste Problem. Der Zeitpunkt der Freigabe ähnelt dem Verhalten von Threads. Wo? ⇒ Viele asynchrone Anwendungen steuern die Ereignisschleife oder den Scheduler zum Zeitpunkt der E / A-Anweisung. Geben Sie die Steuerung frei, wenn Sie auf die E / A-Verarbeitung warten.

Was ist der Unterschied? ⇒ ** Thread ** ist auf einen Thread auf Systemebene zurückzuführen. ** Das Betriebssystem kann den laufenden Thread jederzeit unterbrechen ** und die Kontrolle an andere Threads übergeben. Bei der ** asynchronen Programmierung ** können ** Aufgaben nicht durch Ereignisschleifen unterbrochen werden. ** (Nicht präemptives Multitasking)

Was Sie (wahrscheinlich) bei asynchroner Programmierung minimal halten müssen

Python läuft auf dem Betriebssystem und konkurriert um andere Prozesse und Ressourcen. Mit anderen Worten, das Betriebssystem steuert alle Prozesse. Bei einer asynchronen Anwendung wird die Verarbeitung durch einen Scheduler-Interrupt unterbrochen. Wenn die Steuerung zurückgegeben wird, wird sie an dem Ort fortgesetzt, an dem sie unterbrochen wurde. Dies ist beim Multithreading und Multiprocessing nicht immer der Fall. Ebenfalls, In ** Multiprozessen und Threads ** wird die neu zu startende Aufgabe vom OS-Scheduler ** festgelegt. Bei der ** asynchronen Programmierung ** entscheidet die Anwendung **, welche Aufgabe fortgesetzt werden soll.

async und await in Python

Reservierte Wörter "asynchron" und "warten"

Verwenden Sie "async" vor der "def" -Anweisung, um ein neues Collout (parallele Task) zu definieren. Die Ausführung der Collout-Funktion wird entsprechend der definierten Situation unterbrochen und fortgesetzt. Selbst wenn die durch "async" definierte Funktion aufgerufen wird, wird die Funktion nicht vor Ort ausgeführt und ein ** Collout-Objekt ** wird zurückgegeben. Das Folgende ist ein Implementierungsbeispiel.

>>> async def asyc_hello():
...   print("Hello")
...
>>> asyc_hello()
<coroutine object asyc_hello at 0x000001D3D021C748>

Sie können sehen, dass asyc_hello () ein Collout-Objekt anstelle des Standardausgabewerts von print (" Hello ") zurückgibt. Was ist ein Collout-Objekt? Wie soll ich damit umgehen? Ich werde diesen Bereich grob erklären. Sie müssen etwas erstellen, um ein Collout-Objekt auszuführen. Es ist eine ** Ereignisschleife **. Unten finden Sie den Code, der die Ereignisschleife erstellt und das Collout-Objekt ausgeführt hat.

>>> import asyncio
>>> async def asyncio_hello():
...     print("Hallo")
...
>>> loop = asyncio.get_event_loop()
>>> loop.run_until_complete(asyncio_hello())
Hallo
>>> loop.close()

Erstellen Sie eine Ereignisschleife mit asyncio.get_event_loop () Das Collout-Objekt wird von run_until_complete (asyncio_hello ()) ausgeführt. Als nächstes erkläre ich die Grundlagen der Ereignisschleife.

Über die Ereignisschleife

In diesem Artikel werden keine Begriffe zu Ereignisschleifen erläutert. Anstatt die Ereigniswarteschlange, den Ereignisverteiler, den Ereignishandler, die Rückruffunktion usw. zu erläutern, konzentrierte ich mich auf die Funktionsweise des Ereignisschleifenmechanismus und drückte aus, was ich in der Abbildung gelernt habe. Unten ist die Abbildung. Der Einfachheit halber haben wir den Ausdruck "Ereignis" in "Anfrage" geändert. (Der Einfachheit halber ist es einfacher, sich persönlich ein Bild davon zu machen.) イベントループ完成図1.png

Informationen zu Collout-Objekten

Kehren wir zum Umgang mit kolloutierten Objekten zurück. Das Collout-Objekt wird in der Ereignisschleife ausgeführt. Außerdem wird es in der Ereignisschleife in die Warteschlange gestellt, und das Collout-Objekt unternimmt nichts, bis es an die Reihe kommt. Der folgende Quellcode ist der Code, der nur ein einfaches Collout vorbereitet und die Ereignisschleife ausführt.

asyncprint.py


import asyncio

async def print_numeber(number):
    print(number)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()

    loop.run_until_complete(
        asyncio.wait([
            print_numeber(number)
            for number in range(10)
        ])
    )
    loop.close()
$ python src/asyncpritn.py
2
4
8
6
9
5
1
3
7
0

Dies ist der grundlegende Ablauf des obigen Codes.

  1. Erstellen Sie eine Ereignisschleife: asyncio.get_event_loop ()
  2. Erstellen oder fügen Sie eine Aufgabe hinzu: asyncio.get_event_loop (). Create_task () oderasyncio.wait ()
  3. Führen Sie die Ereignisschleife aus: asyncio.get_event_loop (). Run_until_complete ()
  4. Schließen Sie die Ereignisschleife explizit: asyncio.get_event_loop (). Close ()

Als nächstes ist es ein Beispiel, wenn das reservierte Wort "Warten" zu "asyncio.wait ()" hinzugefügt wird.

corowait.py


import time 
import random
import asyncio

async def waiter(name):
    for _ in range(4):
        time_to_sleep = random.randint(1,3)/4
        time.sleep(time_to_sleep)
        print(
            "{}Ist{}Wartete eine Sekunde"
            "".format(name, time_to_sleep)
        )

async def main():
    await asyncio.wait([waiter("foo"), waiter("bar")])

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
$time python corowait.py
foo ist 0.5 Sekunden gewartet
foo ist 0.25 Sekunden gewartet
foo ist 0.75 Sekunden gewartet
foo ist 0.25 Sekunden gewartet
Balken ist 0.25 Sekunden gewartet
Balken ist 0.75 Sekunden gewartet
Balken ist 0.75 Sekunden gewartet
Balken ist 0.25 Sekunden gewartet

real    0m4.416s
user    0m0.130s                                                                                      sys     0m0.013s  

wait 'wartet, bis das Collout die Ausführung zurückgibt, gibt dann die Steuerung frei und übergibt sie an die Ereignisschleife, bis die Ausführung abgeschlossen ist. Hier wird die Verarbeitung durch die Funktion time.sleep ()` blockiert. Daher wird es ein synchroner Prozess und die Prozesse werden der Reihe nach ausgeführt. In Python gibt es eine Funktion "asycio.sleep ()", mit der die Blockierungsverarbeitung in eine nicht blockierende Verarbeitung und eine asynchrone Verarbeitung geändert werden kann. Auf diese Weise ist es möglich, eine asynchrone Verarbeitung auszuführen. Unten finden Sie einen Beispielcode.

cowait_improved.py


import time 
import random
import asyncio

async def waiter(name):
    for _ in range(4):
        time_to_sleep = random.randint(1,3)/4
        await asyncio.sleep(time_to_sleep)
        print(
            "{}Ist{}Wartete eine Sekunde"
            "".format(name, time_to_sleep)
        )

async def main():
    await asyncio.wait([waiter("foo"), waiter("bar")])

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
$time python corowait_improved.py
foo ist 0.25 Sekunden gewartet
Balken ist 0.75 Sekunden gewartet
foo ist 0.75 Sekunden gewartet
Balken ist 0.75 Sekunden gewartet
foo ist 0.75 Sekunden gewartet
Balken ist 0.25 Sekunden gewartet
foo ist 0.25 Sekunden gewartet
Balken ist 0.25 Sekunden gewartet

real    0m2.442s
user    0m0.161s                                                                                      sys     0m0.017s  

Die Funktionen "foo" und "bar" werden abwechselnd ausgeführt, wodurch die Verarbeitungsgeschwindigkeit verbessert wird. Dies bedeutet, dass Corroutine die Kontrolle kooperativ freigegeben hat.

Verweise

https://www.atmarkit.co.jp/ait/articles/1103/23/news101_2.html Einführung in Python3 Expert Python Programming Revised 2nd Edition

Recommended Posts

[Python] Erfahren Sie mehr über asynchrone Programmierung und Ereignisschleifen
Erfahren Sie mehr über das Programmieren
Über Python für Schleife
Erste Schritte mit Python3 # 2 Erfahren Sie mehr über Typen und Variablen
Programmieren mit Python und Tkinter
Informationen zu Python-Objekten und -Klassen
Informationen zu Python-Variablen und -Objekten
Paiza Python Primer 1 Programmieren lernen
Über Python, len () und randint ()
Über Python und reguläre Ausdrücke
Informationen zu Python- und Betriebssystemoperationen
Python # Über Referenz und Kopie
Über Python sort () und reverse ()
[Einführung in Python3 Tag 1] Programmierung und Python
Über Python-Diktat und sortierte Funktionen
Über Python und Cython dtype
Über Python Pickle (cPickle) und Marschall
[Python] Über Executor und zukünftige Klassen
Über Python, aus und importieren, als
Vergleichen Sie Python- und JavaScript-Array-Schleifen
Vermeiden Sie verschachtelte Schleifen in PHP und Python
Lerne Python und AI verwandte englische Wörter. .. ..
Lerne Mathematik und Englisch durch Programmieren (Teil 1)
Eine Geschichte über Python Pop und Append
Apropos alte und neue Klassen in Python
Über _ und __
Lerne Mathematik und Englisch durch Programmieren (Teil 2)
Apropos Python-Klassenattribute und Metaklassen
Was ist "funktionale Programmierung" und "objektorientiert"? Python Edition
Denken Sie an Suchvorgänge mit Tiefenpriorität und Breitenpriorität in Python
Über den Unterschied zwischen "==" und "is" in Python
Eine Geschichte über das Ändern von Python und das Hinzufügen von Funktionen
Über flache und tiefe Kopien von Python / Ruby
Über Python-Slices
Über die Einschlussnotation von Python
Python-Programmierhinweis
Über Python tqdm.
Über Python, Klasse
Informationen zur Python-Vererbung
Programmieren mit Python
Über Python, range ()
Informationen zur Python-Referenz
Über Python-Dekorateure
[Python] Über Multi-Prozess
Lerne Python-Gesten
Asynchrone Verarbeitung von Python ~ Asynchron vollständig verstehen und warten ~
Informationen zum Erstellen und Ändern von benutzerdefinierten Designs für Python IDLE
Paiza Python Primer 2: Lernen Sie bedingte Verzweigungs- und Vergleichsoperatoren
Lernen Sie die asynchrone Verarbeitung / Collouts von Python im Vergleich zu Node.js
Erfahren Sie mehr über die Druckfunktion und die Zeichenfolgen von Python für Anfänger.
[Python] Kapitel 01-02 Über Python (Ausführung und Installation der Entwicklungsumgebung)