Поиск…


Вступление

В этой статье мы обсудим, как появилась концепция Eventloop и как ее можно использовать для высокопроизводительных серверов и приложений, управляемых событиями, таких как графические интерфейсы.

Как эволюционировала концепция цикла событий.

Eventloop в псевдокоде

Цикл событий представляет собой цикл, ожидающий событий, а затем реагирует на эти события

while true:
    wait for something to happen
    react to whatever happened

Пример однопоточного HTTP-сервера без цикла события

    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)

Вот простая форма HTTP-сервера, которая представляет собой однопоточный, но не цикл событий. Проблема здесь в том, что он ждет, пока каждый запрос не будет закончен, прежде чем начинать обработку следующего. Если для чтения заголовков HTTP-запросов или для извлечения файла с диска требуется некоторое время, мы сможем начать обработку следующего запроса, пока мы ждем его завершения.

Наиболее распространенное решение - сделать программу многопоточной.

Пример многопоточного HTTP-сервера без цикла события

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)

Теперь мы сделали наш небольшой HTTP-сервер многопоточным. Таким образом, мы можем сразу перейти к следующему запросу, поскольку текущий запрос выполняется в фоновом потоке. Многие серверы, включая Apache, используют этот подход.

Но это не идеально. Одно ограничение состоит в том, что вы можете создавать только столько потоков. Для рабочих нагрузок, где у вас огромное количество подключений, но каждое подключение требует только внимания каждый раз, многопоточная модель не будет работать очень хорошо. Решением для этих случаев является использование цикла событий:

Пример HTTP-сервера с циклом события

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)

Надеюсь, этот псевдокод понятен. Вот что происходит: мы ждем, когда что-то случится. Всякий раз, когда создается новое соединение или существующее соединение требует нашего внимания, мы решаем его, а затем возвращаемся к ожиданию. Таким образом, мы хорошо себя чувствуем, когда есть много соединений, и каждый из них редко требует внимания.

В реальном приложении (не псевдокоде), запущенном в Linux, часть «ожидание следующего события» будет реализована путем вызова системного вызова poll () или epoll (). «Начало чтения / записи чего-то в сокет» будет реализовано путем вызова системных вызовов recv () или send () в неблокирующем режиме.

Ссылка:

[1]. «Как работает цикл событий?» [Онлайн]. Доступно: https://www.quora.com/How-does-an-event-loop-work



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow