Qual é a diferença entre libev e libevent?

96

Ambas as duas libs são projetadas para agendamento assíncrono de i / o e ambas envolvem epoll no linux e kqueue no FreeBSD, etc.

Exceto diferenças superficiais, quero dizer, qual é a diferença VERDADEIRA entre essas duas bibliotecas? em relação à arquitetura ou filosofia de design?

cifra
fonte
1
libevent também suporta IOCP para janelas (através de bufferevent AFAIK) que libev não
rogerdpack
1
rogerdpack, suporte libuv IOCP github.com/joyent/libuv
Denis Denisov

Respostas:

223

Quanto à filosofia de design, libev foi criado para melhorar algumas das decisões arquitetônicas em libevent, por exemplo, o uso de variáveis ​​globais dificultou o uso de libevent com segurança em ambientes multithread. As estruturas do observador são grandes porque combinam I / O, tempo e sinal manipuladores em um, os componentes extras, como os servidores http e dns, sofriam de má qualidade de implementação e problemas de segurança resultantes, e os temporizadores eram inexatos e não lidavam bem com os saltos de tempo.

Libev tentou melhorar cada um deles, não usando variáveis ​​globais, mas usando um contexto de loop para todas as funções, usando pequenos observadores para cada tipo de evento (um observador de I / O usa 56 bytes em x86_64 em comparação com 136 para libevent), permitindo tipos de eventos, como temporizadores baseados em relógio de parede vs. tempo monotônico, interrupções entre threads, preparar e verificar observadores para incorporar outros loops de evento ou para serem incorporados e assim por diante.

O problema do componente extra é "resolvido" por não tê-los, então libev pode ser pequeno e eficiente, mas você também precisa procurar em outro lugar por uma biblioteca http, porque libev simplesmente não tem uma (por exemplo, há um biblioteca muito relacionada chamada libeio que faz I / O assíncrona, que pode ser usada independentemente ou junto com a libev, para que você possa misturar e combinar).

Resumindo, libev tenta fazer apenas uma coisa (biblioteca de eventos POSIX), e isso da maneira mais eficiente possível. Libevent tenta fornecer a solução completa (event lib, biblioteca de E / S sem bloqueio, servidor http, cliente DNS).

Ou, ainda mais resumido, libev tenta seguir a filosofia da caixa de ferramentas do UNIX de fazer apenas uma coisa, o melhor possível.

Observe que essa é a filosofia de design, que posso afirmar com autoridade porque projetei o libev. Se essas metas de design foram realmente alcançadas ou se a filosofia é baseada em princípios sólidos, depende de você julgar.

Atualização de 2017:

Fui questionado várias vezes sobre a inexatidão do timer a que me refiro e por que o libev não oferece suporte a IOCPs no Windows.

Quanto aos cronômetros, o libevent agenda cronômetros relativos a algum tempo base desconhecido que está no futuro, sem você saber. Libev pode lhe dizer com antecedência qual horário base ele usará para agendar temporizadores, o que permite que programas usem tanto a abordagem libevent quanto a abordagem libev. Além disso, o libevent às vezes expirava os temporizadores mais cedo, dependendo do backend. O primeiro é um problema de API, o último pode ser corrigido (e pode ter sido corrigido desde então - eu não verifiquei).

Quanto ao suporte IOCP - não acho que possa ser feito, pois os IOCPs simplesmente não são poderosos o suficiente. Por um lado, eles precisam de um tipo de socket especial, o que limitaria o conjunto de identificadores permitidos no Windows ainda mais (por exemplo, os sopckets usados ​​por perl são do tipo "errado" para IOCPs). Além disso, os IOCPs simplesmente não suportam eventos de prontidão de E / S, eles só podem fazer E / S reais. Existem soluções alternativas para alguns tipos de identificador, como fazer uma leitura fictícia de 0 byte, mas, novamente, isso limitaria os tipos de identificador que você pode usar no Windows ainda mais e, além disso, dependeria de um comportamento não documentado que provavelmente não é compartilhado por todos os provedores de soquete .

Até onde sei, nenhuma outra biblioteca de eventos oferece suporte a IOCPs no Windows. O que libevent faz é, além da biblioteca de eventos, permitir que você enfileire operações de leitura / gravação que podem ser feitas via IOCPs. Como a libev não faz E / S para você, não há como usar IOCPs na própria libev.

Isso é de fato intencional - libev tenta ser pequeno e semelhante ao POSIX, e o Windows simplesmente não tem uma maneira eficiente de obter eventos de E / S no estilo POSIX. Se os IOCPs forem importantes, você mesmo terá que usá-los ou, de fato, usar alguns dos muitos outros frameworks que fazem E / S para você e, portanto, podem usar os IOCPs.

Lembre-se da monica
fonte
Marc você é o autor do libeio também?
juanpavergara,
infelizmente, ele foi removido e substituído por libuv: github.com/joyent/libuv/issues/485 e este: groups.google.com/forum/#!topic/nodejs/UwHkaOksprw
Peter Teoh
1
Fiz uma boa adição à libev chamada libevfibers, que adiciona um nível de fibra em cima da libev, libcoro e libeio. Pode ser encontrado aqui: github.com/Lupus/libevfibers
Lupus
1
libevé doloroso na plataforma Windows. O compilador MinGW sempre sigfault on ++activecnt(function ev_ref) e não entendo como resolver esse problema. O segundo problema é usar a selectinterface de soquete antiga com nossa versão IOCP moderna de interoperação de soquete. Você poderia melhorar o suporte ao Widnows?
Vitold S.
1
Desculpe ter que dizer, mas parece haver outra "filosofia" por trás do libev, que quebrou muitos projetos de código aberto. Evidente, por exemplo, em lists.schmorp.de/pipermail/libev/2017q1/002710.html ou lists.schmorp.de/pipermail/libev/2010q1/000912.html . Os usuários em potencial provavelmente também devem considerar isso.
dbrank0
13

A grande vantagem do libevent para mim é o suporte integrado ao OpenSSL. A interface Bufferevent, introduzida na versão 2.0 da API libevent , lida com as conexões seguras quase sem dor para o desenvolvedor. Pode ser que meu conhecimento esteja desatualizado, mas parece que o libev não suporta isso.

Vitaly Isaev
fonte
3
Correto: libev não faz I / O para você e, portanto, não faz TLS para você (ou, de fato, qualquer I / O).
Lembre