Node.js
slinga
Sök…
Introduktion
I det här inlägget kommer vi att diskutera hur konceptet Eventloop uppstod och hur det kan användas för högpresterande servrar och händelsedrivna applikationer som GUI: er.
Hur konceptet med händels loop utvecklades.
Eventloop i pseudokod
En händelsslinga är en slinga som väntar på händelser och sedan reagerar på dessa händelser
while true:
wait for something to happen
react to whatever happened
Exempel på en enkeltrådad HTTP-server utan händels loop
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)
Här är en enkel form av en HTTP-server som är en enda gängad men ingen händels loop. Problemet här är att det väntar tills varje begäran är klar innan du börjar behandla nästa. Om det tar en stund att läsa rubrikerna för HTTP-begäran eller att hämta filen från disken, borde vi kunna börja behandla nästa förfrågan medan vi väntar på att den är klar.
Den vanligaste lösningen är att göra programmet flertrådigt.
Exempel på en multi-gängad HTTP-server utan händels loop
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)
Nu har vi gjort vår lilla HTTP-server multigängad. På det här sättet kan vi omedelbart gå vidare till nästa förfrågan eftersom den aktuella begäran körs i en bakgrundstråd. Många servrar, inklusive Apache, använder den här metoden.
Men det är inte perfekt. En begränsning är att du bara kan spaja så många trådar. För arbetsbelastningar där du har ett stort antal anslutningar, men varje anslutning bara kräver uppmärksamhet varje gång i taget, fungerar inte den multi-gängade modellen särskilt bra. Lösningen för dessa fall är att använda en händelsslinga:
Exempel på en HTTP-server med händels loop
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)
Förhoppningsvis är denna pseudokod förståelig. Här är vad som händer: Vi väntar på att saker och ting ska hända. När en ny anslutning skapas eller en befintlig anslutning behöver vår uppmärksamhet, tar vi upp den och återgår till att vänta. På det sättet presterar vi bra när det finns många anslutningar och var och en sällan kräver bara sällan uppmärksamhet.
I en verklig applikation (inte pseudokod) som körs på Linux skulle delen "vänta på att nästa händelse skulle hända" implementeras genom att ringa systemet för samtal () eller epoll (). Delarna av "börja läsa / skriva något till en socket" skulle implementeras genom att ringa recv () eller skicka () systemsamtal i icke-blockerande läge.
Referens:
[1]. "Hur fungerar en evenemangslinga?" [Uppkopplad]. Tillgängligt: https://www.quora.com/How-does-an-event-loop-work