Node.js
Eventloop
Recherche…
Introduction
Dans cet article, nous allons discuter de la manière dont le concept Eventloop a émergé et de la manière dont il peut être utilisé pour les serveurs hautes performances et les applications pilotées par des événements telles que les interfaces graphiques.
Comment le concept de boucle d'événement a évolué.
Eventloop en pseudo-code
Une boucle d'événement est une boucle qui attend des événements et réagit à ces événements
while true:
wait for something to happen
react to whatever happened
Exemple de serveur HTTP mono-thread sans boucle d'événement
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)
Voici une forme simple d'un serveur HTTP qui est un thread unique mais pas de boucle d'événement. Le problème ici est qu'il attend que chaque requête soit terminée avant de commencer à traiter la suivante. S'il faut un certain temps pour lire les en-têtes de requête HTTP ou pour extraire le fichier du disque, nous devrions pouvoir commencer à traiter la requête suivante en attendant que cela se termine.
La solution la plus courante consiste à rendre le programme multithread.
Exemple de serveur HTTP multithread sans boucle d'événement
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)
Maintenant, nous avons rendu notre petit serveur HTTP multi-thread. De cette façon, nous pouvons immédiatement passer à la requête suivante car la requête en cours est exécutée dans un thread d'arrière-plan. De nombreux serveurs, y compris Apache, utilisent cette approche.
Mais ce n'est pas parfait. Une limitation est que vous ne pouvez générer que beaucoup de threads. Pour les charges de travail où vous avez un grand nombre de connexions, mais chaque connexion ne nécessite qu'une attention de temps en temps, le modèle multi-thread ne fonctionnera pas très bien. La solution pour ces cas est d'utiliser une boucle d'événement:
Exemple de serveur HTTP avec boucle d'événements
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)
Espérons que ce pseudo-code soit intelligible. Voici ce qui se passe: nous attendons que les choses se passent. Chaque fois qu'une nouvelle connexion est créée ou qu'une connexion existante nécessite notre attention, nous nous en occupons, puis revenons à l'attente. De cette façon, nous fonctionnons bien quand il y a beaucoup de connexions et que chacune d'elles nécessite rarement une attention.
Dans une application réelle (pas de pseudocode) fonctionnant sous Linux, la partie "Attendre l'événement suivant" serait implémentée en appelant l'appel système poll () ou epoll (). Les parties "commencer à lire / écrire quelque chose dans un socket" seraient implémentées en appelant les appels système recv () ou send () en mode non bloquant.
Référence:
[1]. "Comment fonctionne une boucle d'événement?" [En ligne]. Disponible: https://www.quora.com/How-does-an-event-loop-work