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 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.
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.
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)
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 PythonVerwenden 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.
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.)
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.
asyncio.get_event_loop ()
asyncio.get_event_loop (). Create_task ()
oderasyncio.wait ()
asyncio.get_event_loop (). Run_until_complete ()
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.
https://www.atmarkit.co.jp/ait/articles/1103/23/news101_2.html Einführung in Python3 Expert Python Programming Revised 2nd Edition
Recommended Posts