Me interesarían aspectos como:
- alcance / características
- actuación
- madurez
c++
boost
boost-asio
libuv
oberstet
fuente
fuente
Respuestas:
Alcance
Boost.Asio es una biblioteca de C ++ que comenzó con un enfoque en las redes, pero sus capacidades de E / S asíncronas se han extendido a otros recursos. Además, con Boost.Asio como parte de las bibliotecas de Boost, su alcance se reduce ligeramente para evitar la duplicación con otras bibliotecas de Boost. Por ejemplo, Boost.Asio no proporcionará una abstracción de subproceso, ya que Boost.Thread ya proporciona uno.
Por otro lado, libuv es una biblioteca de C diseñado para ser la capa de plataforma para Node.js . Proporciona una abstracción para IOCP en Windows, kqueue en macOS y epoll en Linux. Además, parece que su alcance ha aumentado ligeramente para incluir abstracciones y funcionalidades, como hilos, agrupaciones de hilos y comunicación entre hilos.
En esencia, cada biblioteca proporciona un bucle de eventos y capacidades de E / S asíncronas. Se superponen para algunas de las características básicas, como temporizadores, sockets y operaciones asincrónicas. libuv tiene un alcance más amplio y proporciona funcionalidad adicional, como abstracciones de hilos y sincronización, operaciones de sistemas de archivos síncronos y asíncronos, gestión de procesos, etc. capacidades, como ICMP, SSL, operaciones de bloqueo sincrónico y sin bloqueo, y operaciones de nivel superior para tareas comunes, incluida la lectura de una secuencia hasta que se recibe una nueva línea.
Lista de características
Aquí está la breve comparación lado a lado de algunas de las principales características. Dado que los desarrolladores que usan Boost.Asio a menudo tienen otras bibliotecas de Boost disponibles, he optado por considerar bibliotecas de Boost adicionales si se proporcionan directamente o son triviales de implementar.
1. dispersión / agrupación I / O .
2. Boost.Extension nunca se envió para su revisión a Boost. Como se señaló aquí , el autor lo considera completo.
Bucle de eventos
Si bien tanto libuv como Boost.Asio proporcionan bucles de eventos, existen algunas diferencias sutiles entre los dos:
uv_default_loop()
), en lugar de crear un nuevo bucle (uv_loop_new()
), ya que otro componente puede estar ejecutando el bucle predeterminado.io_service
son sus propios bucles que permiten ejecutar múltiples subprocesos. Para admitir este Boost.Asio realiza un bloqueo interno a costa de cierto rendimiento . El historial de revisión de Boost.Asio indica que ha habido varias mejoras de rendimiento para minimizar el bloqueo.Threadpool
uv_queue_work
. El tamaño del conjunto de hilos es configurable a través de la variable de entornoUV_THREADPOOL_SIZE
. El trabajo se ejecutará fuera del bucle de eventos y dentro del conjunto de hilos. Una vez que se completa el trabajo, el controlador de finalización se pondrá en cola para ejecutarse dentro del bucle de eventos.io_service
puede funcionar fácilmente como uno solo porqueio_service
permite invocar varios subprocesosrun
. Esto pone la responsabilidad de la gestión de hilos y el comportamiento del usuario, como se puede ver en este ejemplo.Subprocesos y sincronización
Operaciones del sistema de archivos
Redes
EAGAIN
oEWOULDBLOCK
.Señal
kill
y manejo de señal con suuv_signal_t
tipo yuv_signal_*
operaciones.kill
, perosignal_set
proporciona manejo de señal.IPC
uv_pipe_t
tipo.local::stream_protocol::socket
olocal::datagram_protocol::socket
, ywindows::stream_handle
.Diferencias API
Si bien las API son diferentes según el idioma solo, aquí hay algunas diferencias clave:
Asociación de Operadores y Manipuladores
Dentro de Boost.Asio, hay un mapeo uno a uno entre una operación y un controlador. Por ejemplo, cada
async_write
operación invocará al WriteHandler una vez. Esto es cierto para muchas de las operaciones y controladores de libuv. Sin embargo, libuv'suv_async_send
admite un mapeo de muchos a uno. Variasuv_async_send
llamadas pueden provocar que se llame a uv_async_cb una vez.Call Chains vs. Watcher Loops
Cuando se trata de tareas, como leer desde un flujo / UDP, manejar señales o esperar temporizadores, las cadenas de llamadas asíncronas de Boost.Asio son un poco más explícitas. Con libuv, se crea un observador para designar intereses en un evento en particular. Luego se inicia un bucle para el observador, donde se proporciona una devolución de llamada. Al recibir el evento de intereses, se invocará la devolución de llamada. Por otro lado, Boost.Asio requiere que se emita una operación cada vez que la aplicación esté interesada en manejar el evento.
Para ayudar a ilustrar esta diferencia, aquí hay un ciclo de lectura asíncrono con Boost.Asio, donde la
async_receive
llamada se emitirá varias veces:Y aquí está el mismo ejemplo con libuv, donde
handle_read
se invoca cada vez que el observador observa que el socket tiene datos:Asignación de memoria
Como resultado de las cadenas de llamadas asincrónicas en Boost.Asio y los observadores en libuv, la asignación de memoria a menudo ocurre en diferentes momentos. Con los observadores, libuv difiere la asignación hasta después de recibir un evento que requiere memoria para manejar. La asignación se realiza a través de una devolución de llamada del usuario, invocada internamente a libuv, y difiere la responsabilidad de desasignación de la aplicación. Por otro lado, muchas de las operaciones Boost.Asio requieren que la memoria se asigne antes de emitir la operación asincrónica, como el caso de
buffer
forasync_read
. Boost.Asio proporcionanull_buffers
, que se puede usar para escuchar un evento, permitiendo que las aplicaciones difieran la asignación de memoria hasta que se necesite memoria, aunque esto está en desuso.Esta diferencia de asignación de memoria también se presenta dentro del
bind->listen->accept
bucle. Con libuv,uv_listen
crea un bucle de eventos que invocará la devolución de llamada del usuario cuando una conexión esté lista para ser aceptada. Esto permite que la aplicación difiera la asignación del cliente hasta que se intente una conexión. Por otro lado, Boost.Asiolisten
solo cambia el estado de laacceptor
. Lasasync_accept
escuchas para el evento de conexión, y requiere que la pareja se asignarán antes de ser invocado.Actuación
Desafortunadamente, no tengo ningún número de referencia concreto para comparar libuv y Boost.Asio. Sin embargo, he observado un rendimiento similar al usar las bibliotecas en aplicaciones en tiempo real y casi en tiempo real. Si se desean números duros, la prueba de referencia de libuv puede servir como punto de partida.
Además, aunque se debe realizar un perfil para identificar cuellos de botella reales, tenga en cuenta las asignaciones de memoria. Para libuv, la estrategia de asignación de memoria se limita principalmente a la devolución de llamada del asignador. Por otro lado, la API de Boost.Asio no permite una devolución de llamada del asignador, y en su lugar empuja la estrategia de asignación a la aplicación. Sin embargo, los controladores / devoluciones de llamada en Boost.Asio pueden copiarse, asignarse y desasignarse. Boost.Asio permite que las aplicaciones proporcionen funciones de asignación de memoria personalizadas para implementar una estrategia de asignación de memoria para los manejadores.
Madurez
Boost.Asio
El desarrollo de Asio se remonta al menos a OCT-2004, y fue aceptado en Boost 1.35 el 22-MAR-2006 después de someterse a una revisión por pares de 20 días. También sirvió como implementación de referencia y API para la propuesta de biblioteca de red para TR2 . Boost.Asio tiene una buena cantidad de documentación , aunque su utilidad varía de usuario a usuario.
La API también tiene una sensación bastante consistente. Además, las operaciones asincrónicas son explícitas en el nombre de la operación. Por ejemplo,
accept
es bloqueo síncrono yasync_accept
es asíncrono. La API proporciona funciones gratuitas para tareas de E / S comunes, por ejemplo, leer desde una secuencia hasta que\r\n
se lea una. También se ha prestado atención para ocultar algunos detalles específicos de la red, como laip::address_v4::any()
representación de la dirección de "todas las interfaces"0.0.0.0
.Finalmente, Boost 1.47+ proporciona un seguimiento de controladores , que puede resultar útil al depurar, así como compatibilidad con C ++ 11.
libuv
Según sus gráficos de github, el desarrollo de Node.js se remonta al menos a FEB-2009 , y el desarrollo de libuv a MAR-2011 . El uvbook es un gran lugar para una introducción a libuv. La documentación de la API está aquí .
En general, la API es bastante consistente y fácil de usar. Una anomalía que puede ser una fuente de confusión es que
uv_tcp_listen
crea un circuito de observación. Esto es diferente de otros observadores de que generalmente tienen unauv_*_start
yuv_*_stop
par de funciones para controlar la vida del bucle observador. Además, algunas de lasuv_fs_*
operaciones tienen una cantidad decente de argumentos (hasta 7). Con el comportamiento sincrónico y asincrónico que se determina en presencia de una devolución de llamada (el último argumento), la visibilidad del comportamiento sincrónico puede verse disminuida.Finalmente, un rápido vistazo al libuv historial de confirmación de muestra que los desarrolladores son muy activos.
fuente
uv_async_send
llamadas y manejarlas todas con una sola devolución de llamada. Está documentado aquí . Además, gracias a todos.Okay. Tengo cierta experiencia en el uso de ambas bibliotecas y puedo aclarar algunas cosas.
Primero, desde un punto de vista conceptual, estas bibliotecas son bastante diferentes en diseño. Tienen arquitecturas diferentes, porque son de diferente escala. Boost.Asio es una gran biblioteca de red destinada a ser utilizada con protocolos TCP / UDP / ICMP, POSIX, SSL, etc. Libuv es solo una capa para la abstracción multiplataforma de IOCP para Node.js, predominantemente. Entonces, libuv es funcionalmente un subconjunto de Boost.Asio (características comunes solo hilos de sockets TCP / UDP, temporizadores). Siendo ese el caso, podemos comparar estas bibliotecas usando solo unos pocos criterios:
Integración con nuevas características de C ++: Asio es mejor (Asio 1.51 usa ampliamente el modelo asíncrono C ++ 11, mueve semántica, plantillas variadas). En cuanto a la madurez, Asio es un proyecto más estable y maduro con buena documentación (si se compara con libuv descripción de encabezados), mucha información a través de Internet (videoconferencias, blogs: http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg = 1 , etc.) e incluso libros (no para profesionales, sin embargo: http://en.highscore.de/cpp/boost/index.html ). Libuv tiene solo un libro en línea (pero también bueno) http://nikhilm.github.com/uvbook/index.htmly varias videoconferencias, por lo que será difícil conocer todos los secretos (esta biblioteca tiene muchos de ellos). Para una discusión más específica de las funciones, vea mis comentarios a continuación.
Como conclusión, debería decir que todo depende de sus propósitos, su proyecto y lo que concretamente tiene la intención de hacer.
fuente
Una gran diferencia es que el autor de Asio (Christopher Kohlhoff) está preparando su biblioteca para su inclusión en la Biblioteca estándar de C ++, consulte http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175 .pdf y http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html
fuente
Agregar el estado de portabilidad: a partir de la publicación de esta respuesta y de acuerdo con mis propios intentos:
fuente