Ereignisgesteuerte Programmierung

Die ereignisgesteuerte Programmierung konzentriert sich auf Ereignisse. Schließlich hängt der Programmfluss von Ereignissen ab. Bisher beschäftigten wir uns entweder mit sequentiellen oder parallelen Ausführungsmodellen, aber das Modell mit dem Konzept der ereignisgesteuerten Programmierung wird als asynchrones Modell bezeichnet. Die ereignisgesteuerte Programmierung hängt von einer Ereignisschleife ab, die immer auf die neuen eingehenden Ereignisse wartet. Die Funktionsweise der ereignisgesteuerten Programmierung hängt von Ereignissen ab. Sobald sich ein Ereignis wiederholt, entscheiden die Ereignisse, was und in welcher Reihenfolge ausgeführt werden soll. Das folgende Flussdiagramm hilft Ihnen zu verstehen, wie dies funktioniert -

Python-Modul - Asyncio

Das Asyncio-Modul wurde in Python 3.4 hinzugefügt und bietet eine Infrastruktur zum Schreiben von Single-Threaded-Concurrent-Code mithilfe von Co-Routinen. Im Folgenden sind die verschiedenen Konzepte aufgeführt, die vom Asyncio-Modul verwendet werden:

Die Ereignisschleife

Die Ereignisschleife ist eine Funktion zum Behandeln aller Ereignisse in einem Rechencode. Es wirkt während der Ausführung des gesamten Programms auf dem Weg und verfolgt den Eingang und die Ausführung von Ereignissen. Das Asyncio-Modul ermöglicht eine einzelne Ereignisschleife pro Prozess. Im Folgenden sind einige Methoden aufgeführt, die vom Asyncio-Modul zum Verwalten einer Ereignisschleife bereitgestellt werden:

  • loop = get_event_loop() - Diese Methode stellt die Ereignisschleife für den aktuellen Kontext bereit.

  • loop.call_later(time_delay,callback,argument) - Diese Methode sorgt für den Rückruf, der nach den angegebenen time_delay Sekunden aufgerufen werden soll.

  • loop.call_soon(callback,argument)- Diese Methode sorgt für einen Rückruf, der so schnell wie möglich aufgerufen werden soll. Der Rückruf wird aufgerufen, nachdem call_soon () zurückgegeben wurde und wenn das Steuerelement zur Ereignisschleife zurückkehrt.

  • loop.time() - Diese Methode wird verwendet, um die aktuelle Zeit gemäß der internen Uhr der Ereignisschleife zurückzugeben.

  • asyncio.set_event_loop() - Diese Methode setzt die Ereignisschleife für den aktuellen Kontext auf die Schleife.

  • asyncio.new_event_loop() - Diese Methode erstellt ein neues Ereignisschleifenobjekt und gibt es zurück.

  • loop.run_forever() - Diese Methode wird ausgeführt, bis die Methode stop () aufgerufen wird.

Beispiel

Das folgende Beispiel für eine Ereignisschleife hilft beim Drucken hello worldmit der Methode get_event_loop (). Dieses Beispiel stammt aus den offiziellen Python-Dokumenten.

import asyncio

def hello_world(loop):
   print('Hello World')
   loop.stop()

loop = asyncio.get_event_loop()

loop.call_soon(hello_world, loop)

loop.run_forever()
loop.close()

Ausgabe

Hello World

Futures

Dies ist kompatibel mit der Klasse concurrent.futures.Future, die eine Berechnung darstellt, die nicht durchgeführt wurde. Es gibt folgende Unterschiede zwischen asyncio.futures.Future und concurrent.futures.Future -

  • Die Methoden result () und exception () verwenden kein Timeout-Argument und lösen eine Ausnahme aus, wenn die Zukunft noch nicht abgeschlossen ist.

  • Mit add_done_callback () registrierte Rückrufe werden immer über call_soon () der Ereignisschleife aufgerufen.

  • Die Klasse asyncio.futures.Future ist nicht mit den Funktionen wait () und as_completed () im Paket concurrent.futures kompatibel.

Beispiel

Das folgende Beispiel hilft Ihnen beim Verständnis der Verwendung der Klasse asyncio.futures.future.

import asyncio

async def Myoperation(future):
   await asyncio.sleep(2)
   future.set_result('Future Completed')

loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(Myoperation(future))
try:
   loop.run_until_complete(future)
   print(future.result())
finally:
   loop.close()

Ausgabe

Future Completed

Coroutinen

Das Konzept der Coroutinen in Asyncio ähnelt dem Konzept des Standard-Thread-Objekts unter dem Threading-Modul. Dies ist die Verallgemeinerung des Unterprogrammkonzepts. Eine Coroutine kann während der Ausführung angehalten werden, so dass sie auf die externe Verarbeitung wartet und von dem Punkt zurückkehrt, an dem sie zum Zeitpunkt der externen Verarbeitung gestoppt wurde. Die folgenden zwei Möglichkeiten helfen uns bei der Implementierung von Coroutinen:

async def function ()

Dies ist eine Methode zur Implementierung von Coroutinen unter dem Asyncio-Modul. Es folgt ein Python-Skript für dasselbe -

import asyncio

async def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

Ausgabe

First Coroutine

@ asyncio.coroutine Dekorateur

Eine andere Methode zur Implementierung von Coroutinen besteht darin, Generatoren mit dem Dekorator @ asyncio.coroutine zu verwenden. Es folgt ein Python-Skript für dasselbe -

import asyncio

@asyncio.coroutine
def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

Ausgabe

First Coroutine

Aufgaben

Diese Unterklasse des Asyncio-Moduls ist für die parallele Ausführung von Coroutinen innerhalb einer Ereignisschleife verantwortlich. Das folgende Python-Skript ist ein Beispiel für die parallele Verarbeitung einiger Aufgaben.

import asyncio
import time
async def Task_ex(n):
   time.sleep(1)
   print("Processing {}".format(n))
async def Generator_task():
   for i in range(10):
      asyncio.ensure_future(Task_ex(i))
   int("Tasks Completed")
   asyncio.sleep(2)

loop = asyncio.get_event_loop()
loop.run_until_complete(Generator_task())
loop.close()

Ausgabe

Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9

Transporte

Das Asyncio-Modul bietet Transportklassen für die Implementierung verschiedener Kommunikationsarten. Diese Klassen sind nicht threadsicher und werden nach dem Einrichten des Kommunikationskanals immer mit einer Protokollinstanz gepaart.

Im Folgenden sind verschiedene Arten von Transporten aufgeführt, die vom BaseTransport geerbt wurden:

  • ReadTransport - Dies ist eine Schnittstelle für schreibgeschützte Transporte.

  • WriteTransport - Dies ist eine Schnittstelle für Nur-Schreib-Transporte.

  • DatagramTransport - Dies ist eine Schnittstelle zum Senden der Daten.

  • BaseSubprocessTransport - Ähnlich der BaseTransport-Klasse.

Es folgen fünf verschiedene Methoden der BaseTransport-Klasse, die anschließend über die vier Transporttypen hinweg vorübergehend sind:

  • close() - Es schließt den Transport.

  • is_closing() - Diese Methode gibt true zurück, wenn der Transport geschlossen wird oder bereits geschlossen ist.

  • get_extra_info(name, default = none) - Dies gibt uns einige zusätzliche Informationen über den Transport.

  • get_protocol() - Diese Methode gibt das aktuelle Protokoll zurück.

Protokolle

Das Asyncio-Modul bietet Basisklassen, die Sie zur Implementierung Ihrer Netzwerkprotokolle in Unterklassen unterteilen können. Diese Klassen werden in Verbindung mit Transporten verwendet; Das Protokoll analysiert eingehende Daten und fordert zum Schreiben ausgehender Daten auf, während der Transport für die eigentliche E / A und Pufferung verantwortlich ist. Es folgen drei Protokollklassen:

  • Protocol - Dies ist die Basisklasse für die Implementierung von Streaming-Protokollen zur Verwendung mit TCP- und SSL-Transporten.

  • DatagramProtocol - Dies ist die Basisklasse zum Implementieren von Datagrammprotokollen zur Verwendung mit UDP-Transporten.

  • SubprocessProtocol - Dies ist die Basisklasse für die Implementierung von Protokollen, die mit untergeordneten Prozessen über eine Reihe von unidirektionalen Pipes kommunizieren.