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



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow