Um mehrere Verbindungen in Python zu verarbeiten, können wir Forking und Threading verwenden , um asynchrone Eingabe- und Ausgabeprozesse zu generieren, mit denen wir mehrere Verbindungen gleichzeitig verarbeiten können.
Gabeln und Einfädeln
Wenn wir in den ersten Schritten sind, in denen wir Programmieren lernen, oder wenn wir nur strukturiertes Programmieren durchgeführt haben, scheinen diese Begriffe vielleicht kompliziert zu sein, aber sie sind einfach zu verstehen und zu verdauen. Sehen wir uns die Definitionen an, bevor wir fortfahren.
Forking : Dies ist ein Begriff, der in UNIX- Umgebungen verwendet wird und darin besteht, eine Verzweigung vorzunehmen. Bei einem Prozess, den wir duplizieren, haben wir zwei gleiche Prozesse, aber jeder mit seinem Gültigkeitsbereich ist der ursprüngliche Prozess als übergeordneter Prozess und der doppelte Prozess als der Wenn wir also eine Analogie zur Science-Fiction herstellen, können wir sie als parallele Universen betrachten, in denen dieselben Dinge existieren, die sich in denselben Punkten nur unterschiedlich verhalten können.
Der Nachteil von Forking ist, dass es auf Ressourcenebene sehr teuer sein kann und wir daher das Threading haben. Ein Thread ist ein Thread. In diesem Fall sind die Threads Unterprozesse, die zu demselben Prozess gehören und Speicher und Ressourcen gemeinsam nutzen Auf diese Weise senken wir die Kosten für die Prozessorressourcen. Wenn wir jedoch den Speicher gemeinsam nutzen, stellen wir das Problem fest, dass wir mit den Elementen, auf die die Threads zugreifen können, sehr vorsichtig sein müssen, um nicht zu beeinträchtigten Vorgängen zu führen.
Nachdem wir die Theorie und die grundlegenden Konzepte kennen, werden wir einige Beispiele sehen, anhand derer wir die Anwendung in Python sehen können .
Wie wir eingangs sagten, ist es dank der großen Anzahl von Modulen und Bibliotheken in Python sehr einfach, Programme mit Netzwerkfunktionalitäten zu erstellen, sodass wir uns auf die Logik anstatt auf die technischen Aspekte konzentrieren können.
Sehen wir uns im folgenden Bild ein Beispiel für Forking an und erklären dann, was mit dem Code passiert:
Das erste, was wir tun, ist das Importieren der benötigten Module von SocketServer . Wichtig ist, dass ForkingMixIn dafür zuständig ist, die Duplizierung der Prozesse bei jeder Anforderung zu verwalten. Anschließend definieren wir die Klasse Server und Handler . In Handler platzieren wir einen Konstruktor Wenn Sie festlegen, was mit den eingehenden Verbindungen geschehen soll, erhalten Sie den Namen des Clients und erstellen einen Bildschirmausdruck einer Nachricht. Schließlich instanziieren wir die Klasse Server, übergeben die Parameter, zuerst den Port, an dem Verbindungen akzeptiert werden, und dann den Klassenhandler. Schließlich rufen wir die Methode serve_forever auf, um den Server zu starten und damit die Anforderungen der Clients zu verwalten.
Wie wir sehen, ist diese Anwendung recht einfach. Sehen wir uns an, wie wir mit Threads etwas Ähnliches erreichen können. In der folgenden Abbildung sehen wir ein Beispiel:
Wir können sehen, dass es fast genau derselbe Code ist, mit dem Unterschied, dass anstelle von ForkingMixIn ThreadingMixIn verwendet wird. Dies sind also die Schlüsselbibliotheken für dieses Verhalten, wenn Programme erstellt werden, die mehrere Verbindungen akzeptieren.