Comment se compare-t-elle avec Boost/ASIO?

je serais intéressé par des aspects comme:

  • domaine d'application/Caractéristiques
  • performance
  • maturité
199
demandé sur Sam Miller 2012-07-11 03:22:42

3 réponses

domaine d'application

coup de pouce.Asio est une bibliothèque C++ qui a commencé avec un accent sur la mise en réseau, mais ses capacités d'E/S asynchrones ont été étendues à d'autres ressources. En outre, avec le coup de pouce.Asio faisant partie des bibliothèques Boost, sa portée est légèrement réduite pour éviter la duplication avec d'autres bibliothèques Boost. Par exemple, le coup de pouce.Asio ne fournira pas d'abstraction de thread, comme Boost.Le fil fournit déjà un.

d'autre part, libuv est une bibliothèque C conçue pour être la couche plate-forme pour noeud.js . Il fournit une abstraction à IOCP Pour Windows et libev sur les systèmes Unix. Bien qu'il ya des efforts pour supprimer libev comme indiqué dans cette question. En outre, il semble que son champ d'application ait légèrement augmenté pour inclure les abstractions et des fonctionnalités telles que les threads, les threadpools et la communication inter-thread.

au cœur de chaque bibliothèque, on trouve une boucle d'événements et des fonctions d'E/S asynchrones. Ils se chevauchent pour certaines des caractéristiques de base, comme les minuteries, les sockets et les opérations asynchrones. libuv a une portée plus large et fournit des fonctionnalités supplémentaires, telles que des abstractions de thread et de synchronisation, des opérations de systèmes de fichiers synchrones et asynchrones, la gestion de processus, etc. Dans revanche, coup de pouce.Le focus réseau original d'Asio fait surface, car il fournit un ensemble plus riche de capacités réseau connexes, telles que ICMP, SSL, opérations de blocage synchrone et non-blocage, et des opérations de plus haut niveau pour les tâches communes, y compris la lecture d'un flux jusqu'à la réception d'une nouvelle ligne.


"1519420920 Fonction" Liste

Voici la brève comparaison côte à côte sur certains des traits majeurs. Depuis que les développeurs utilisent Stimuler.Asio a souvent D'autres bibliothèques Boost disponibles, j'ai choisi d'envisager des bibliothèques Boost supplémentaires si elles sont directement fournies ou triviales à mettre en œuvre.

                         libuv          Boost
Event Loop:              yes            Asio
Threadpool:              yes            Asio + Threads
Threading:              
  Threads:               yes            Threads
  Synchronization:       yes            Threads
File System Operations:
  Synchronous:           yes            FileSystem
  Asynchronous:          yes            Asio + Filesystem
Timers:                  yes            Asio
Scatter/Gather I/O[1]:    no             Asio
Networking:
  ICMP:                  no             Asio
  DNS Resolution:        async-only     Asio
  SSL:                   no             Asio
  TCP:                   async-only     Asio
  UDP:                   async-only     Asio
Signal:
  Handling:              yes            Asio
  Sending:               yes            no
IPC:
  UNIX Domain Sockets:   yes            Asio
  Windows Named Pipe:    yes            Asio
Process Management:
  Detaching:             yes            Process
  I/O Pipe:              yes            Process
  Spawning:              yes            Process
System Queries:
  CPU:                   yes            no
  Network Interface:     yes            no
Serial Ports:            no             yes
TTY:                     yes            no
Shared Library Loading:  yes            Extension[2]

1. Scatter/Gather I / O .

2. coup de pouce.L'Extension n'a jamais été soumise à L'examen de Boost. Comme indiqué ici , l'auteur considère qu'il est compléter.

Boucle

alors que les deux libuv et Boost.Asio fournir des boucles d'événement, il ya quelques différences subtiles entre les deux:

  • bien que libuv supporte plusieurs boucles d'événements, il ne supporte pas l'exécution de la même boucle à partir de plusieurs threads. Pour cette raison, il faut être prudent lors de l'utilisation de la boucle par défaut ( uv_default_loop() ), plutôt que de créer une nouvelle boucle ( uv_loop_new() ), comme autre composant peut être en cours d'exécution par défaut de la boucle.
  • coup de pouce.Asio n'ont pas la notion de boucle par défaut; tous les io_service sont leurs propres boucles qui permettent d'exécuter plusieurs threads. À l'appui de ce coup de pouce.Asio exécute verrouillage interne au coût de quelque performance . Stimuler.La révision d'Asio historique indique qu'il y a eu plusieurs améliorations de performance pour minimiser le verrouillage.

pool de threads

  • libuv's fournit un threadpool à travers uv_queue_work . La taille de threadpool est un détail d'implémentation, et ne semble pas être configurable par L'API. Le travail sera exécuté en dehors de la boucle d'événement et à l'intérieur du threadpool. Une fois le travail terminé, le gestionnaire d'achèvement sera mis en file d'attente pour exécuter dans la boucle d'événements.
  • Pendant Que Boost.Asio ne fournit pas de threadpool, le io_service peut facilement fonctionner comme un résultat de io_service permettant à plusieurs threads d'invoquer run . Cela place la responsabilité de la gestion du thread et du comportement à l'utilisateur, comme on peut le voir dans cet exemple .

Threading et la Synchronisation

  • libuv fournit une abstraction aux types de threads et de synchronisation.
  • coup de pouce.Thread fournit un thread et des types de synchronisation. Beaucoup de ces types suivent de près la norme C++11, mais fournissent aussi quelques extensions. Comme un résultat de Boost.Asio permet à plusieurs threads d'exécuter une boucle d'événement unique, il fournit strands comme un moyen de créer une invocation séquentielle des gestionnaires d'événements sans utiliser de mécanismes de verrouillage explicites.

Opérations Du Système De Fichiers

  • libuv fournit une abstraction à de nombreuses opérations du système de fichiers. Il y a une fonction par opération, et chaque opération peut être soit un blocage synchrone ou asynchrone. Si un callback est fourni, alors l'opération sera exécutée asynchrone dans un threadpool interne. Si un rappel n'est pas fourni, alors l'appel sera synchrone bloquant.
  • coup de pouce.Le système de fichiers fournit des appels de blocage synchrones pour de nombreuses opérations du système de fichiers. Ceux-ci peuvent être combinés avec Boost.Asio et un threadpool pour créer des opérations de système de fichiers asynchrones.

mise en Réseau

  • libuv prend en charge les opérations asynchrones sur les sockets UDP et TCP, ainsi que la résolution DNS. Les développeurs d'applications doivent être conscients que les descripteurs de fichiers sont mis à la non-bloquant. Par conséquent, les opérations natives synchrones doivent vérifier les valeurs de retour et errno pour EAGAIN ou EWOULDBLOCK .
  • coup de pouce.Asio est un peu plus riche dans son soutien au réseautage. En outre, de nombreuses fonctionnalités offertes par le réseau de libuv, Boost.Asio supporte les sockets SSL et ICMP. En Outre, Boost.Asio fournit des opérations de blocage et de non-blocage synchrones, en plus de ses opérations asynchrones. Il existe de nombreuses fonctions autonomes qui fournissent des opérations communes de niveau supérieur., comme la lecture d'un montant fixe d'octets, ou jusqu'à ce qu'un délimiteur spécifié caractère est lu.

Signal

  • libuv fournit une abstraction kill et le traitement du signal avec ses opérations de type uv_signal_t et uv_signal_* . au moment , seule la boucle d'événement par défaut supporte les signaux.
  • coup de pouce.Asio ne fournit pas une abstraction à kill , mais son signal_set_service assure le traitement des signaux.

CIB


API Differences

bien que les API soient différentes en fonction de la langue seule, voici quelques différences clés:

Opération et Gestionnaire de l'Association

Sous Boost.Asio, il y a une correspondance entre une opération et un gestionnaire. Par exemple, chaque async_write opération va invoquer le WriteHandler une fois. Cela est vrai pour beaucoup d'opérations et de manipulateurs de libuv. Cependant, le uv_async_send de libuv supporte un mappage à plusieurs. Les appels multiples uv_async_send peuvent entraîner le uv_async_cb à être appelé une fois.

Appel Chaînes vs Watcher Boucles

lorsqu'il s'agit de tâches telles que la lecture d'un flux / UDP, la manipulation de signaux ou l'attente de minuteries, Stimuler.Les chaînes d'appels asynchrones d'Asio sont un peu plus explicites. Avec libuv, un observateur est créé pour désigner les intérêts dans un événement particulier. Une boucle est alors lancé pour l'observateur, lorsqu'un rappel est prévu. À la réception de l'événement d'intérêts, le rappel sera invoqué. D'autre part, de Stimuler l'.Asio exige qu'une opération soit délivrée chaque fois que la demande est intéressée par le traitement de l'événement.

pour illustrer cette différence, voici un boucle de lecture asynchrone avec Boost.Asio, où l'appel async_receive sera émis plusieurs fois:

void start()
{
  socket.async_receive( buffer, handle_read ); ----.
}                                                  |
    .----------------------------------------------'
    |      .---------------------------------------.
    V      V                                       |
void handle_read( ... )                            |
{                                                  |
  std::cout << "got data" << std::endl;            |
  socket.async_receive( buffer, handle_read );   --'
}    

Et voici le même exemple avec libuv, où handle_read est invoqué chaque fois que l'observateur observe que la socket a des données:

uv_read_start( socket, alloc_buffer, handle_read ); --.
                                                      |
    .-------------------------------------------------'
    |
    V
void handle_read( ... )
{
  fprintf( stdout, "got data\n" );
}

Allocation Mémoire

comme résultat des chaînes d'appel asynchrones dans Boost.Asio et les observateurs dans libuv, l'allocation de la mémoire se produit souvent à différents temps. Avec watchers, libuv reporte l'allocation jusqu'à ce qu'il reçoive un événement nécessitant de la mémoire. L'attribution se fait par le biais d'un rappel utilisateur, invoqué à l'intérieur de libuv, et défère la responsabilité de désallocation de l'application. D'autre part, beaucoup de coup de pouce.Les opérations Asio exigent que la mémoire soit attribuée avant d'émettre l'opération asynchrone, comme dans le cas du buffer pour async_read . Stimuler.Asio ne fournir null_buffers , qui peut être utilisé pour écouter un événement, permettant aux applications de reporter l'allocation de mémoire jusqu'à ce que la mémoire est nécessaire.

cette différence d'allocation de mémoire se présente également à l'intérieur de la boucle bind->listen->accept . Avec libuv, uv_listen crée une boucle d'événement qui va invoquer le rappel de l'utilisateur lorsqu'une connexion est prête à être acceptée. Cela permet à l'application de reporter l'attribution du client jusqu'à ce qu'une connexion est tentée. Sur l'autre main, Stimuler.Le listen d'Asio ne change que l'état du acceptor . Le async_accept écoute l'événement de connexion, et exige que le pair soit alloué avant d'être invoqué.


Performance

malheureusement, je n'ai pas de chiffres de référence concrets pour comparer libuv et Boost.Asio. Cependant, j'ai observé performances similaires en utilisant les bibliothèques dans des applications en temps réel et quasi-réel. Si l'on désire des nombres durs, le "test de référence" 15192150920 de libuv peut servir de point de départ.

en outre, bien que le profilage devrait être fait pour identifier les goulots d'étranglement réels, être conscient des allocations de mémoire. Pour libuv, la stratégie d'allocation de mémoire est principalement limitée à la callback de l'allocateur. D'autre part, de Stimuler l'.L'API d'Asio ne permet pas un allocator de rappel, et les pousse au contraire à la stratégie de répartition de l'application. Cependant, les handlers/callbacks dans Boost.Asio peut être copié, attribué et désalloué. Stimuler.Asio permet aux applications de fournir des fonctions custom memory allocation afin de mettre en œuvre une stratégie d'allocation de mémoire pour les gestionnaires.


maturité

coup de pouce.Asio

Asio le développement de l'dates retour au moins octobre-2004, et il a été accepté dans Boost 1.35 le 22-mars-2006 après avoir subi un examen par les pairs de 20 jours. Il a également servi d'implémentation de référence et D'API pour proposition de bibliothèque de réseau pour TR2 . Stimuler.Asio dispose d'une quantité raisonnable de documentation , bien que son utilité varie d'un utilisateur à l'autre.

L'API ont également une sensation assez cohérente. En outre, les opérations asynchrones sont explicites dans l'opération du nom. Par exemple, accept est un blocage synchrone et async_accept est asynchrone. L'API fournit des fonctions libres pour les tâches d'E/S communes, par exemple, la lecture d'un flux jusqu'à ce qu'un \r\n soit lu. Une attention a également été accordée à cacher certains détails spécifiques au réseau, comme le ip::address_v4::any() représentant l'adresse "Toutes les interfaces" de 0.0.0.0 .

enfin, Boost 1.47 + fournit handler tracking , ce qui peut s'avérer utile lors du débogage, ainsi que le C++11.

libuv

basé sur leurs graphes github, noeud.le développement de js remonte au moins à FEB-2009 , et le développement de libuv date de MAR-2011 . Le uvbook est un endroit idéal pour une introduction à la libuv. L'API est documentée sous la forme d'un en-tête détaillé, mais on pourrait encore avoir besoin de contributions dans certains domaines.

dans l'ensemble, L'API est assez cohérente et facile à utiliser. Une anomalie qui peut être source de confusion est que uv_tcp_listen crée une boucle d'observateur. Ceci est différent des autres observateurs qui ont généralement une paire de fonctions uv_*_start et uv_*_stop pour contrôler la vie de la boucle de l'observateur. En outre, certaines des opérations uv_fs_* ont un nombre décent d'arguments (jusqu'à 7). Avec le synchrone et comportement asynchrone étant déterminé sur la présence d'un rappel (le dernier argument), la visibilité du comportement synchrone peut être diminuée.

Enfin, un rapide coup d'œil à la libuv commettre l'histoire montre que les développeurs sont très actifs.

432
répondu Tanner Sansbury 2017-10-06 07:41:23

Ok. J'ai une certaine expérience dans l'utilisation des deux bibliothèques et je peux clarifier certaines choses.

tout d'abord, d'un point de vue conceptuel, ces bibliothèques sont très différentes dans leur conception. Ils ont des architectures différentes, parce qu'ils sont d'une échelle différente. Stimuler.Asio est une grande bibliothèque de réseaux destinée à être utilisée avec les protocoles TCP/UDP/ICMP, POSIX, SSL, etc. Libuv est juste une couche pour l'abstraction multiplate-forme de IOCP pour Noeud.js, principalement. Ainsi, libuv est fonctionnellement un sous-ensemble de Boost.Asio (caractéristiques communes seulement TCP/UDP Sockets threads,timers). Cela étant, nous pouvons comparer ces bibliothèques en utilisant seulement quelques critères:

  1. intégration avec noeud.js-Libuv est considérablement mieux car il est destiné à cela (nous pouvons l'intégrer complètement et l'utiliser dans tous les aspects, par exemple dans le cloud comme windows azure). Mais Asio implémente aussi presque la même fonctionnalité que dans Node.js file d'attente d'événements axée sur l'environnement.
  2. IOCP Performance-Je ne pouvais pas voir de grandes différences, parce que ces deux bibliothèques abstraient L'API sous-jacente OS. Mais ils le font d'une manière différente: Asio utilise massivement des fonctionnalités C++ comme les templates et parfois TMP. Libuv est une bibliothèque C native. Mais néanmoins la réalisation de L'IOCP est très efficace. Les sockets UDP en Asio ne sont pas assez bons il est préférable d'utiliser libuv pour eux.

    intégration avec les nouvelles fonctionnalités de C++: Asio est mieux (Asio 1.51 utilisation extensive du modèle asynchrone C++11, sémantique des mouvements, modèles variadiques).En ce qui concerne la maturité, Asio est un projet plus stable et mature avec une bonne documentation (si on la compare à la description des en-têtes de la libuv), beaucoup d'informations sur Internet (Conférences vidéo, blogs: http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=1 , etc.) et même des livres (pas pour les professionnels, mais néanmoins: http://en.highscore.de/cpp/boost/index.html ). Libuv a seulement un livre en ligne (mais aussi bon) http://nikhilm.github.com/uvbook/index.html et plusieurs conférences vidéo, il sera donc difficile de connaître tous les secrets (cette bibliothèque en a beaucoup). Pour une réflexion plus spécifique de fonctions voir mes commentaires ci-dessous.

en conclusion, je dois dire que tout dépend de vos objectifs, de votre projet et de ce que concrètement vous avez l'intention de le faire.

45
répondu Oleksandr Karaberov 2012-11-02 20:51:32

une énorme différence est l'auteur de Asio (Christopher Kohlhoff) prépare sa bibliothèque pour inclusion dans la bibliothèque Standard C++, voir http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175.pdf et http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html

14
répondu Vinnie Falco 2016-03-25 14:36:57