Eu estaria interessado em aspectos como:
- escopo / recursos
- desempenho
- maturidade
c++
boost
boost-asio
libuv
oberstet
fonte
fonte
Respostas:
Escopo
O Boost.Asio é uma biblioteca C ++ que começou com foco em redes, mas seus recursos de E / S assíncronos foram estendidos a outros recursos. Além disso, com o Boost.Asio fazendo parte das bibliotecas do Boost, seu escopo é ligeiramente reduzido para evitar duplicação com outras bibliotecas do Boost. Por exemplo, o Boost.Asio não fornecerá uma abstração de thread, pois o Boost.Thread já fornece uma.
Por outro lado, libuv é uma biblioteca C concebida para ser a camada plataforma para Node.js . Ele fornece uma abstração para IOCP no Windows, kqueue no macOS e epoll no Linux. Além disso, parece que seu escopo aumentou um pouco para incluir abstrações e funcionalidades, como threads, poços de threads e comunicação entre threads.
Em sua essência, cada biblioteca fornece um loop de eventos e recursos de E / S assíncrona. Eles se sobrepõem a alguns dos recursos básicos, como cronômetros, soquetes e operações assíncronas. O libuv possui um escopo mais amplo e fornece funcionalidades adicionais, como abstrações de encadeamentos e sincronização, operações de sistemas de arquivos síncronos e assíncronos, gerenciamento de processos etc. recursos, como ICMP, SSL, operações de bloqueio síncrono e sem bloqueio e operações de nível superior para tarefas comuns, incluindo leitura de um fluxo até que uma nova linha seja recebida.
Lista de recursos
Aqui está uma breve comparação lado a lado em alguns dos principais recursos. Como os desenvolvedores que usam o Boost.Asio geralmente têm outras bibliotecas do Boost disponíveis, optei por considerar outras bibliotecas do Boost, caso sejam fornecidas diretamente ou sejam triviais para implementar.
1. Dispersão / Recolha de I / O .
2. O Boost.Extension nunca foi enviado para revisão no Boost. Como observado aqui , o autor considera completo.
Loop de Eventos
Enquanto o libuv e o Boost.Asio fornecem loops de eventos, existem algumas diferenças sutis entre os dois:
uv_default_loop()
), em vez de criar um novo loop (uv_loop_new()
), pois outro componente pode estar executando o loop padrão.io_service
são seus próprios loops que permitem a execução de vários threads. Para dar suporte a esse Boost.Asio executa o bloqueio interno ao custo de algum desempenho . O histórico de revisões do Boost.Asio indica que houve várias melhorias de desempenho para minimizar o bloqueio.Grupo de discussão
uv_queue_work
. O tamanho do conjunto de encadeamentos é configurável por meio da variável de ambienteUV_THREADPOOL_SIZE
. O trabalho será executado fora do loop de eventos e dentro do pool de threads. Depois que o trabalho estiver concluído, o manipulador de conclusão será colocado na fila para executar no loop de eventos.io_service
pode funcionar facilmente como um, como resultado daio_service
permissão de vários encadeamentosrun
. Isso coloca a responsabilidade do gerenciamento e comportamento do encadeamento para o usuário, como pode ser visto neste exemplo.Rosqueamento e Sincronização
Operações do sistema de arquivos
Trabalho em rede
EAGAIN
orEWOULDBLOCK
.Sinal
kill
e manipulação de sinal com seuuv_signal_t
tipo euv_signal_*
operações.kill
, massignal_set
fornece tratamento de sinal.IPC
uv_pipe_t
tipo.local::stream_protocol::socket
oulocal::datagram_protocol::socket
, ewindows::stream_handle
.Diferenças de API
Embora as APIs sejam diferentes apenas com base no idioma, aqui estão algumas diferenças importantes:
Associação de Operação e Manipulador
No Boost.Asio, há um mapeamento individual entre uma operação e um manipulador. Por exemplo, cada
async_write
operação chamará o WriteHandler uma vez. Isso é verdade para muitas operações e manipuladores libuv. No entanto, o libuv'suv_async_send
suporta um mapeamento muitos-para-um. Váriasuv_async_send
chamadas podem resultar no uv_async_cb sendo chamado uma vez.Cadeias de chamada x loops de observador
Ao lidar com tarefas, como ler de um fluxo / UDP, manipular sinais ou aguardar temporizadores, as cadeias de chamadas assíncronas do Boost.Asio são um pouco mais explícitas. Com o libuv, um observador é criado para designar interesses em um evento específico. Um loop é iniciado para o observador, onde é fornecido um retorno de chamada. Ao receber o evento de interesse, o retorno de chamada será invocado. Por outro lado, o Boost.Asio exige que uma operação seja emitida sempre que o aplicativo estiver interessado em lidar com o evento.
Para ajudar a ilustrar essa diferença, aqui está um loop de leitura assíncrono com o Boost.Asio, em que a
async_receive
chamada será emitida várias vezes:E aqui está o mesmo exemplo com o libuv, onde
handle_read
é invocado cada vez que o observador observa que o soquete possui dados:Alocação de memória
Como resultado das cadeias de chamadas assíncronas no Boost.Asio e dos observadores no libuv, a alocação de memória geralmente ocorre em momentos diferentes. Com os observadores, o libuv adia a alocação até depois de receber um evento que requer memória para lidar. A alocação é feita por meio de um retorno de chamada do usuário, invocado interno ao libuv e adia a responsabilidade de desalocação do aplicativo. Por outro lado, muitas das operações do Boost.Asio exigem que a memória seja alocada antes de emitir a operação assíncrona, como é o caso do
buffer
forasync_read
. O Boost.Asio fornecenull_buffers
, que pode ser usado para escutar um evento, permitindo que os aplicativos adiem a alocação de memória até que a memória seja necessária, embora isso seja preterido.Essa diferença de alocação de memória também se apresenta dentro do
bind->listen->accept
loop. Com o libuv,uv_listen
cria um loop de eventos que chamará o retorno de chamada do usuário quando uma conexão estiver pronta para ser aceita. Isso permite que o aplicativo adie a alocação do cliente até que uma conexão esteja sendo tentada. Por outro lado, o Boost.Asio'slisten
apenas altera o estado doacceptor
. Eleasync_accept
escuta o evento de conexão e exige que o par seja alocado antes de ser chamado.atuação
Infelizmente, não tenho números de referência concretos para comparar o libuv e o Boost.Asio. No entanto, observei um desempenho semelhante usando as bibliotecas em aplicativos em tempo real e quase em tempo real. Se números desejados são desejados, o teste de referência da libuv pode servir como ponto de partida.
Além disso, enquanto a criação de perfil deve ser feita para identificar gargalos reais, esteja ciente das alocações de memória. Para o libuv, a estratégia de alocação de memória é principalmente limitada ao retorno de chamada do alocador. Por outro lado, a API do Boost.Asio não permite um retorno de chamada do alocador e envia a estratégia de alocação ao aplicativo. No entanto, os manipuladores / retornos de chamada no Boost.Asio podem ser copiados, alocados e desalocados. O Boost.Asio permite que os aplicativos forneçam funções personalizadas de alocação de memória para implementar uma estratégia de alocação de memória para manipuladores.
Maturidade
Boost.Asio
O desenvolvimento da Asio remonta a pelo menos OCT-2004 e foi aceito no Boost 1.35 em 22 de março de 2006 após uma revisão por pares de 20 dias. Também serviu como implementação de referência e API para a proposta de biblioteca de rede para TR2 . O Boost.Asio possui uma boa quantidade de documentação , embora sua utilidade varie de usuário para usuário.
A API também tem uma sensação bastante consistente. Além disso, as operações assíncronas são explícitas no nome da operação. Por exemplo,
accept
é um bloqueio síncrono easync_accept
é assíncrono. A API fornece funções gratuitas para tarefas comuns de E / S, por exemplo, lendo de um fluxo até que um\r\n
seja lido. Também foi dada atenção para ocultar alguns detalhes específicos da rede, como aip::address_v4::any()
representação do endereço "todas as interfaces" de0.0.0.0
.Por fim, o Boost 1.47+ fornece rastreamento de manipulador , que pode ser útil na depuração, além de suporte ao C ++ 11.
libuv
Com base em seus gráficos no github, o desenvolvimento do Node.js. remonta a pelo menos fevereiro de 2009 e o desenvolvimento do libuv data de MAR-2011 . O uvbook é um ótimo lugar para uma introdução ao libuv. A documentação da API está aqui .
No geral, a API é bastante consistente e fácil de usar. Uma anomalia que pode ser uma fonte de confusão é
uv_tcp_listen
a criação de um loop de observador. Isso é diferente de outros observadores que geralmente têm umuv_*_start
e umuv_*_stop
par de funções para controlar a vida do loop do observador. Além disso, algumas dasuv_fs_*
operações têm uma quantidade razoável de argumentos (até 7). Com o comportamento síncrono e assíncrono sendo determinado na presença de um retorno de chamada (o último argumento), a visibilidade do comportamento síncrono pode ser diminuída.Finalmente, uma rápida olhada no histórico do libuv commit mostra que os desenvolvedores são muito ativos.
fonte
uv_async_send
chamadas e lidar com todas elas com um único retorno de chamada. Está documentado aqui . Além disso, obrigado a todos.Está bem. Tenho alguma experiência no uso das duas bibliotecas e posso esclarecer algumas coisas.
Primeiro, do ponto de vista conceitual, essas bibliotecas são bastante diferentes no design. Eles têm arquiteturas diferentes, porque são de escala diferente. O Boost.Asio é uma grande biblioteca de rede destinada a ser usada com protocolos TCP / UDP / ICMP, POSIX, SSL e assim por diante. O Libuv é apenas uma camada para abstração de plataforma cruzada do IOCP para Node.js, predominantemente. Portanto, o libuv é funcionalmente um subconjunto do Boost.Asio (recursos comuns apenas threads de sockets TCP / UDP, timers). Sendo esse o caso, podemos comparar essas bibliotecas usando apenas alguns critérios:
Integração com os novos recursos do C ++: o Asio é melhor (o Asio 1.51 usa extensivamente o modelo assíncrono do C ++ 11, semântica de movimento, modelos variados). headers description), muitas informações na Internet (videoconferências, blogs: http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg = 1 , etc.) E até livros (não para profissionais, mas mesmo assim: http://en.highscore.de/cpp/boost/index.html ). O Libuv possui apenas um livro on-line (mas também é bom) http://nikhilm.github.com/uvbook/index.htmle várias conversas em vídeo, por isso será difícil conhecer todos os segredos (esta biblioteca possui muitos deles). Para uma discussão mais específica das funções, veja meus comentários abaixo.
Como conclusão, devo dizer que tudo depende dos seus propósitos, do seu projeto e do que concretamente você pretende fazer.
fonte
Uma grande diferença é que o autor de Asio (Christopher Kohlhoff) está preparando sua biblioteca para inclusão na C ++ Standard Library, consulte http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175 .pdf e http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html
fonte
Adicionando o status de portabilidade: Desde a publicação desta resposta e de acordo com minhas próprias tentativas:
fonte