В чем разница между libev и libevent?

96

Обе библиотеки предназначены для асинхронного планирования ввода-вывода, и обе используют epoll в Linux и kqueue во FreeBSD и т. Д.

За исключением поверхностных различий, я имею в виду, в чем ИСТИННАЯ разница между этими двумя библиотеками? Что касается архитектуры или философии дизайна?

шифр
источник
1
libevent также поддерживает IOCP для Windows (через bufferevent AFAIK), чего нет в
libev
1
rogerdpack, поддержка libuv IOCP github.com/joyent/libuv
Денис Денисов

Ответы:

223

Что касается философии проектирования, libev была создана для улучшения некоторых архитектурных решений в libevent, например, использование глобальных переменных затрудняло безопасное использование libevent в многопоточных средах, структуры наблюдателей велики, потому что они объединяют ввод-вывод, время и сигнал обработчики в одном, дополнительные компоненты, такие как серверы http и dns, страдали от плохого качества реализации и, как следствие, проблем с безопасностью, а таймеры были неточными и плохо справлялись с скачками времени.

Либев попытался улучшить каждый из них, не используя глобальные переменные, а используя контекст цикла для всех функций, используя небольшие наблюдатели для каждого типа событий (наблюдатель ввода-вывода использует 56 байтов на x86_64 по сравнению с 136 байтами для libevent), что позволило получить дополнительные типы событий, такие как таймеры, основанные на настенных часах и монотонном времени, межпоточные прерывания, средства подготовки и проверки для встраивания других циклов событий или для встраивания и т. д.

Проблема с дополнительными компонентами "решается" отсутствием их вообще, поэтому libev может быть небольшим и эффективным, но вам также нужно искать в другом месте библиотеку http, потому что у libev ее просто нет (например, есть очень связанная библиотека под названием libeio, которая выполняет асинхронный ввод-вывод, которую можно использовать независимо или вместе с libev, так что вы можете смешивать и сопоставлять).

Короче говоря, libev пытается делать только одну вещь (библиотека событий POSIX), и это наиболее эффективным способом. Libevent пытается предоставить вам полное решение (библиотека событий, неблокирующая библиотека ввода-вывода, http-сервер, DNS-клиент).

Или, что еще короче, libev пытается следовать философии инструментария UNIX, делая только одно, как можно лучше.

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

Обновление 2017:

Меня несколько раз спрашивали, о какой неточности таймера я говорю и почему libev не поддерживает IOCP в Windows.

Что касается таймеров, то libevent планирует таймеры относительно некоторого неизвестного базового времени, которое находится в будущем, без вашего ведома. Libev может заранее сообщить вам, какое базовое время будет использовать для планирования таймеров, что позволяет программам использовать как подход libevent, так и подход libev. Кроме того, в зависимости от серверной части libevent иногда истекал раньше таймеров. Первая проблема связана с API, вторая поправима (и, возможно, с тех пор она была исправлена ​​- я не проверял).

Что касается поддержки IOCP - я не думаю, что это можно сделать, поскольку IOCP просто недостаточно мощны. Во-первых, им нужен специальный тип сокета, который еще больше ограничил бы набор дескрипторов, разрешенных в Windows (например, сокеты, используемые perl, относятся к «неправильному» типу для IOCP). Более того, IOCP просто не поддерживают события готовности ввода-вывода, они могут выполнять только фактический ввод-вывод. Существуют обходные пути для некоторых типов дескрипторов, такие как выполнение фиктивного 0-байтового чтения, но, опять же, это еще больше ограничит типы дескрипторов, которые вы можете использовать в Windows, и, кроме того, будет полагаться на недокументированное поведение, которое, вероятно, не используется всеми поставщиками сокетов. .

Насколько мне известно, никакая другая библиотека событий также не поддерживает IOCP в Windows. В дополнение к библиотеке событий libevent позволяет ставить в очередь операции чтения / записи, которые затем могут выполняться через IOCP. Поскольку libev не выполняет ввод-вывод для вас, в самой libev нет возможности использовать IOCP.

Это действительно сделано намеренно - libev старается быть маленьким и похожим на POSIX, а окна просто не имеют эффективного способа получения событий ввода-вывода в стиле POSIX. Если IOCP важны, вы должны либо использовать их самостоятельно, либо действительно использовать некоторые из многих других фреймворков, которые выполняют ввод-вывод за вас и, следовательно, могут использовать IOCP.

Помни Монику
источник
Марк, ты тоже автор libeio?
juanpavergara 09
к сожалению, он был удален и заменен на libuv: github.com/joyent/libuv/issues/485 и это: groups.google.com/forum/#!topic/nodejs/UwHkaOksprw
Питер Теох
1
Я сделал приятное дополнение к libev под названием libevfibers, оно добавляет уровень волокна поверх libev, libcoro и libeio. Можно найти здесь: github.com/Lupus/libevfibers
Lupus
1
libevболезненно на платформе Windows. Компилятор MinGW всегда sigfault включен ++activecnt(функция ev_ref), и я не понимаю, как решить эту проблему. Вторая проблема заключается в использовании старого selectинтерфейса сокета с нашей современной версией взаимодействия сокетов IOCP. Не могли бы вы улучшить поддержку Widnows?
Витольд С.
2
Извините, что вынужден это сказать, но, похоже, за libev стоит другая «философия», которая сломала многие проекты с открытым исходным кодом. Очевидно, например, в lists.schmorp.de/pipermail/libev/2017q1/002710.html или lists.schmorp.de/pipermail/libev/2010q1/000912.html . Потенциальные пользователи, вероятно, тоже должны это учитывать.
dbrank0
13

Для меня большим преимуществом libevent является встроенная поддержка OpenSSL. Интерфейс Bufferevent, представленный в версии API libevent 2.0, почти безболезненно обрабатывает безопасные соединения для разработчика. Возможно, мои знания устарели, но похоже, что libev этого не поддерживает.

Виталий Исаев
источник
3
Правильно: libev не выполняет ввод-вывод для вас и, следовательно, не выполняет для вас TLS (или, фактически, любой ввод-вывод).
Помните Монику