Node.js
Eventloop
Suche…
Einführung
In diesem Beitrag werden wir diskutieren, wie das Konzept von Eventloop entstand und wie es für Hochleistungsserver und ereignisgesteuerte Anwendungen wie GUIs verwendet werden kann.
Wie sich das Konzept der Ereignisschleife entwickelt hat.
Eventloop im Pseudocode
Eine Ereignisschleife ist eine Schleife, die auf Ereignisse wartet und dann auf diese Ereignisse reagiert
while true:
wait for something to happen
react to whatever happened
Beispiel für einen Single-Thread-HTTP-Server ohne Ereignisschleife
while true:
socket = wait for the next TCP connection
read the HTTP request headers from (socket)
file_contents = fetch the requested file from disk
write the HTTP response headers to (socket)
write the (file_contents) to (socket)
close(socket)
Hier ist eine einfache Form eines HTTP-Servers, der ein einzelner Thread ist, jedoch keine Ereignisschleife. Das Problem hier ist, dass es wartet, bis jede Anforderung abgeschlossen ist, bevor mit der Verarbeitung der nächsten begonnen wird. Wenn es eine Weile dauert, um die HTTP-Anforderungsheader zu lesen oder die Datei von der Festplatte abzurufen, sollten wir in der Lage sein, die nächste Anforderung zu verarbeiten, während wir warten, bis diese abgeschlossen ist.
Die gebräuchlichste Lösung besteht darin, das Programm multithreadig zu machen.
Beispiel für einen Multithread-HTTP-Server ohne Ereignisschleife
function handle_connection(socket):
read the HTTP request headers from (socket)
file_contents = fetch the requested file from disk
write the HTTP response headers to (socket)
write the (file_contents) to (socket)
close(socket)
while true:
socket = wait for the next TCP connection
spawn a new thread doing handle_connection(socket)
Jetzt haben wir unseren kleinen HTTP-Server mit mehreren Threads versehen. Auf diese Weise können wir sofort zur nächsten Anforderung übergehen, da die aktuelle Anforderung in einem Hintergrundthread ausgeführt wird. Viele Server, einschließlich Apache, verwenden diesen Ansatz.
Aber es ist nicht perfekt. Eine Einschränkung ist, dass Sie nur so viele Threads erzeugen können. Bei Workloads, bei denen Sie über eine große Anzahl von Verbindungen verfügen, aber jede Verbindung nur gelegentlich Aufmerksamkeit erfordert, ist das Multithread-Modell nicht besonders leistungsfähig. Die Lösung für diese Fälle ist die Verwendung einer Ereignisschleife:
Beispiel eines HTTP-Servers mit Ereignisschleife
while true:
event = wait for the next event to happen
if (event.type == NEW_TCP_CONNECTION):
conn = new Connection
conn.socket = event.socket
start reading HTTP request headers from (conn.socket) with userdata = (conn)
else if (event.type == FINISHED_READING_FROM_SOCKET):
conn = event.userdata
start fetching the requested file from disk with userdata = (conn)
else if (event.type == FINISHED_READING_FROM_DISK):
conn = event.userdata
conn.file_contents = the data we fetched from disk
conn.current_state = "writing headers"
start writing the HTTP response headers to (conn.socket) with userdata = (conn)
else if (event.type == FINISHED_WRITING_TO_SOCKET):
conn = event.userdata
if (conn.current_state == "writing headers"):
conn.current_state = "writing file contents"
start writing (conn.file_contents) to (conn.socket) with userdata = (conn)
else if (conn.current_state == "writing file contents"):
close(conn.socket)
Hoffentlich ist dieser Pseudocode verständlich. Hier ist was los ist: Wir warten darauf, dass etwas passiert. Immer wenn eine neue Verbindung erstellt wird oder eine bestehende Verbindung unsere Aufmerksamkeit erfordert, gehen wir darauf ein und warten dann wieder. Auf diese Weise arbeiten wir gut, wenn es viele Verbindungen gibt und jede nur selten Aufmerksamkeit erfordert.
In einer echten Anwendung (nicht Pseudocode), die unter Linux ausgeführt wird, wird der Teil "Warten auf das nächste Ereignis" durch Aufrufen des Systemaufrufs poll () oder epoll () implementiert. Die Teile "Lesen / Schreiben von etwas in einen Socket" werden durch Aufruf der Systemaufrufe recv () oder send () im nicht blockierenden Modus implementiert.
Referenz:
[1]. "Wie funktioniert eine Ereignisschleife?" [Online]. Verfügbar: https://www.quora.com/How-does-an-event-loop-work