264

私は次のような側面に興味があります:

  • スコープ/機能
  • パフォーマンス
  • 成熟
4

4 に答える 4

537

範囲

Boost.Asioはネットワーキングに重点を置いて開始されたC++ライブラリですが、その非同期I/O機能は他のリソースに拡張されています。さらに、Boost.AsioはBoostライブラリの一部であるため、他のBoostライブラリとの重複を防ぐために、その範囲はわずかに狭くなっています。たとえば、Boost.Threadはすでにスレッド抽象化を提供しているため、Boost.Asioはスレッド抽象化を提供しません。

一方、libuvは、 Node.jsのプラットフォームレイヤーとして設計されたCライブラリです。これは、 WindowsではIOCP、macOSではkqueue 、Linuxではepollの抽象化を提供します。さらに、その範囲がわずかに拡大して、スレッド、スレッドプール、スレッド間通信などの抽象化と機能が含まれているように見えます。

基本的に、各ライブラリはイベントループと非同期I/O機能を提供します。これらは、タイマー、ソケット、非同期操作などの基本機能の一部で重複しています。libuvはより広い範囲を持ち、スレッドと同期の抽象化、同期および非同期のファイルシステム操作、プロセス管理などの追加機能を提供します。対照的に、Boost.Asioの元のネットワークフォーカスサーフェスは、ネットワーク関連の豊富なセットを提供します。 ICMP、SSL、同期ブロッキングおよび非ブロッキング操作などの機能、および新しい行が受信されるまでのストリームからの読み取りを含む、一般的なタスクの高レベルの操作。


機能リスト

これは、いくつかの主要な機能を並べて比較したものです。Boost.Asioを使用している開発者は、他のBoostライブラリを利用できることが多いため、直接提供されているか、実装が簡単な場合は、追加のBoostライブラリを検討することにしました。

                         libuv Boost
イベントループ:はいAsio
スレッドプール:はいAsio+スレッド
糸脱毛:              
  スレッド:はいスレッド
  同期:はいスレッド
ファイルシステムの操作:
  同期:はいファイルシステム
  非同期:はいAsio+ファイルシステム
タイマー:はいAsio
Scatter / Gather I / O [1]:Asioなし
ネットワーキング:
  ICMP:Asioなし
  DNS解決:非同期のみのAsio
  SSL:Asioなし
  TCP:非同期のみのAsio
  UDP:非同期のみのAsio
信号:
  取り扱い:はいAsio
  送信:はいいいえ
IPC:
  UNIXドメインソケット:はいAsio
  Windows名前付きパイプ:はいAsio
プロセス管理:
  切り離し:はいプロセス
  I / Oパイプ:はいプロセス
  産卵:はいプロセス
システムクエリ:
  CPU:はいいいえ
  ネットワークインターフェース:はいいいえ
シリアルポート:いいえはい
TTY:はいいいえ
共有ライブラリの読み込み:はい拡張機能[2]

1.スキャッター/ギャザーI/O

2. Boost.Extensionは、Boostへのレビューのために送信されたことはありません。ここで述べたように、作者はそれが完全であると考えています。

イベントループ

libuvとBoost.Asioはどちらもイベントループを提供しますが、2つの間にいくつかの微妙な違いがあります。

  • libuvは複数のイベントループをサポートしていますが、複数のスレッドから同じループを実行することはサポートしていません。このため、別のコンポーネントがデフォルトループを実行している可能性があるためuv_default_loop()、新しいループ()を作成するのではなく、デフォルトループ()を使用する場合は注意が必要です。uv_loop_new()
  • Boost.Asioにはデフォルトループの概念がありません。すべてio_serviceが独自のループであり、複数のスレッドを実行できます。このBoost.Asioをサポートするために、パフォーマンスをいくらか犠牲にして内部ロックを実行します。Boost.Asioの改訂履歴は、ロックを最小限に抑えるためにいくつかのパフォーマンスの改善があったことを示しています。

スレッドプール

  • libuvは、を介してスレッドプールを提供しますuv_queue_work。スレッドプールのサイズは、環境変数を介して構成できますUV_THREADPOOL_SIZE。作業は、イベントループの外部およびスレッドプール内で実行されます。作業が完了すると、完了ハンドラーはイベントループ内で実行するためにキューに入れられます。
  • Boost.Asioはスレッドプールを提供していませんが、複数のスレッドがを呼び出すことio_serviceを許可した結果、はスレッドプールとして簡単に機能できます。これにより、この例に示すように、スレッドの管理と動作の責任がユーザーに課せられます。io_servicerun

スレッド化と同期

  • libuvは、スレッドと同期タイプの抽象化を提供します。
  • Boost.Threadは、スレッドと同期のタイプを提供します。これらのタイプの多くはC++11標準に厳密に従いますが、いくつかの拡張機能も提供します。Boost.Asioは、複数のスレッドが単一のイベントループを実行できるようにする結果として、明示的なロックメカニズムを使用せずにイベントハンドラーの順次呼び出しを作成する手段としてストランドを提供します。

ファイルシステムの操作

  • libuvは、多くのファイルシステム操作に抽象化を提供します。操作ごとに1つの関数があり、各操作は同期ブロッキングまたは非同期のいずれかになります。コールバックが提供されている場合、操作は内部スレッドプール内で非同期的に実行されます。コールバックが提供されていない場合、呼び出しは同期ブロッキングになります。
  • Boost.Filesystemは、多くのファイルシステム操作に対して同期ブロッキング呼び出しを提供します。これらをBoost.Asioおよびスレッドプールと組み合わせて、非同期ファイルシステム操作を作成できます。

ネットワーキング

  • libuvは、DNS解決だけでなく、UDPおよびTCPソケットでの非同期操作をサポートします。アプリケーション開発者は、基礎となるファイル記述子が非ブロッキングに設定されていることに注意する必要があります。したがって、ネイティブ同期操作では、またはの戻り値とerrnoを確認する必要があります。EAGAINEWOULDBLOCK
  • Boost.Asioは、ネットワークサポートがもう少し豊富です。さらに、libuvのネットワークが提供する機能の多く、Boost.AsioはSSLおよびICMPソケットをサポートしています。さらに、Boost.Asioは、非同期操作に加えて、同期ブロッキングおよび同期非ブロッキング操作を提供します。設定されたバイト数の読み取りや、指定された区切り文字が読み取られるまでなど、一般的な高レベルの操作を提供する独立した関数が多数あります。

信号

  • libuvは、そのタイプと操作で抽象化killと信号処理を提供します。uv_signal_tuv_signal_*
  • Boost.Asioはに抽象化を提供しませんkillが、signal_set信号処理を提供します。

IPC


APIの違い

APIは言語のみに基づいて異なりますが、いくつかの重要な違いがあります。

操作とハンドラーの関連付け

Boost.Asio内には、操作とハンドラーの間に1対1のマッピングがあります。たとえば、各async_write操作はWriteHandlerを1回呼び出します。これは、多くのlibuv操作とハンドラーに当てはまります。ただし、libuvuv_async_sendは多対1のマッピングをサポートしています。複数uv_async_sendの呼び出しにより、uv_async_cbが1回呼び出される場合があります。

コールチェーンとウォッチャーループ

ストリーム/UDPからの読み取り、シグナルの処理、タイマーの待機などのタスクを処理する場合、Boost.Asioの非同期呼び出しチェーンはもう少し明確です。libuvを使用すると、特定のイベントへの関心を指定するウォッチャーが作成されます。次に、ウォッチャーのループが開始され、コールバックが提供されます。関心のあるイベントを受信すると、コールバックが呼び出されます。一方、Boost.Asioでは、アプリケーションがイベントの処理に関心を持つたびに操作を発行する必要があります。

この違いを説明するために、Boost.Asioを使用した非同期読み取りループを示します。この場合、async_receive呼び出しは複数回発行されます。

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 );   --'
}    

そして、これはlibuvの同じ例です。ここではhandle_read、ウォッチャーがソケットにデータがあることを確認するたびに呼び出されます。

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

メモリ割り当て

Boost.Asioの非同期呼び出しチェーンとlibuvのウォッチャーの結果として、メモリ割り当ては多くの場合、異なる時間に発生します。ウォッチャーの場合、libuvは、処理にメモリを必要とするイベントを受信するまで、割り当てを延期します。割り当てはユーザーコールバックを介して行われ、libuvの内部で呼び出され、アプリケーションの割り当て解除の責任を延期します。一方、Boost.Asio操作の多くは、bufferforの場合のように、非同期操作を発行する前にメモリを割り当てる必要がありますasync_read。Boost.Asioはnull_buffers、イベントをリッスンするために使用できるを提供します。これにより、アプリケーションはメモリが必要になるまでメモリ割り当てを延期できますが、これは非推奨です。

bind->listen->acceptこのメモリ割り当ての違いは、ループ内にも現れます。libuvをuv_listen使用して、接続を受け入れる準備ができたときにユーザーコールバックを呼び出すイベントループを作成します。これにより、アプリケーションは、接続が試行されるまでクライアントの割り当てを延期できます。一方、Boost.Asioはのlisten状態を変更するだけacceptorです。接続イベントをリッスンし、async_accept呼び出される前にピアを割り当てる必要があります。


パフォーマンス

残念ながら、libuvとBoost.Asioを比較するための具体的なベンチマーク数はありません。ただし、リアルタイムおよびほぼリアルタイムのアプリケーションでライブラリを使用すると、同様のパフォーマンスが見られます。難しい数値が必要な場合は、libuvのベンチマークテストが出発点として役立つ場合があります。

さらに、実際のボトルネックを特定するためにプロファイリングを実行する必要がありますが、メモリの割り当てに注意してください。libuvの場合、メモリ割り当て戦略は主にアロケータコールバックに限定されます。一方、Boost.AsioのAPIは、アロケーターコールバックを許可せず、代わりに割り当て戦略をアプリケーションにプッシュします。ただし、Boost.Asioのハンドラー/コールバックは、コピー、割り当て、および割り当て解除される場合があります。Boost.Asioを使用すると、アプリケーションは、ハンドラーのメモリ割り当て戦略を実装するために、カスタムメモリ割り当て機能を提供できます。


成熟

Boost.Asio

Asioの開発は少なくともOCT-2004にまでさかのぼり、20日間のピアレビューを受けた後、2006年3月22日にBoost1.35に受け入れられました。また、TR2のネットワーキングライブラリ提案のリファレンス実装およびAPIとしても機能しました。Boost.Asioにはかなりの量のドキュメントがありますが、その有用性はユーザーによって異なります。

APIもかなり一貫した感触を持っています。さらに、非同期操作は操作の名前で明示されています。たとえば、acceptは同期ブロッキングであり、async_accept非同期です。APIは、一般的なI / Oタスクに無料の機能を提供します。たとえば、ストリームからの読み取りからa\r\nが読み取られるまでです。ip::address_v4::any()の「すべてのインターフェース」アドレスを表すなど、ネットワーク固有の詳細を非表示にすることにも注意が払われています0.0.0.0

最後に、Boost 1.47+は、C ++ 11のサポートだけでなく、デバッグ時に役立つことが証明できるハンドラー追跡を提供します。

libuv

githubグラフに基づくと、Node.jsの開発は少なくともFEB-2009にさかのぼり、libuvの開発はMAR-2011にさかのぼります。uvbookは、libuvを紹介するのに最適な場所です。APIドキュメントはこちらです。

全体として、APIはかなり一貫性があり、使いやすいです。混乱の原因となる可能性のある異常の1つuv_tcp_listenは、ウォッチャーループを作成することです。これは、ウォッチャーループの寿命を制御するための関数と関数のペアを一般的uv_*_startに備えている他のウォッチャーとは異なります。uv_*_stopまた、一部のuv_fs_*操作には、適切な量の引数(最大7つ)があります。コールバック(最後の引数)の存在に基づいて同期および非同期の動作が決定されると、同期の動作の可視性が低下する可能性があります。

最後に、libuvコミット履歴をざっと見ると、開発者が非常にアクティブであることがわかります。

于 2012-11-04T16:38:29.617 に答える
49

Ok。私は両方のライブラリを使用した経験があり、いくつかのことを明確にすることができます。

まず、概念的な観点から、これらのライブラリは設計がまったく異なります。規模が異なるため、アーキテクチャも異なります。Boost.Asioは、TCP / UDP / ICMPプロトコル、POSIX、SSLなどで使用することを目的とした大規模なネットワークライブラリです。Libuvは、主にNode.jsのIOCPのクロスプラットフォーム抽象化のための単なるレイヤーです。したがって、libuvは機能的にBoost.Asioのサブセットです(共通の機能はTCP / UDPソケットスレッド、タイマーのみです)。その場合、いくつかの基準を使用してこれらのライブラリを比較できます。

  1. Node.jsとの統合-Libuvはこれを目的としているため、かなり優れています(完全に統合して、たとえばWindows Azureなどのクラウドなどのすべての側面で使用できます)。ただし、Asioは、Node.jsイベントキュー駆動型環境とほぼ同じ機能も実装しています。
  2. IOCPのパフォーマンス-これらのライブラリは両方とも基盤となるOSAPIを抽象化しているため、大きな違いは見られませんでした。ただし、これは別の方法で行われます。Asioは、テンプレートや場合によってはTMPなどのC++機能を多用します。LibuvはネイティブCライブラリです。しかし、それにもかかわらず、IOCPのAsioの実現は非常に効率的です。AsioのUDPソケットは十分ではなく、libuvを使用することをお勧めします。

    新しいC++機能との統合:Asioの方が優れています(Asio1.51はC++ 11非同期モデル、移動セマンティクス、可変個引数テンプレートを幅広く使用しています)成熟度に関しては、Asioはより安定した成熟したプロジェクトであり、優れたドキュメントを備えています(libuvと比較した場合)ヘッダーの説明)、インターネット全体の多くの情報(ビデオトーク、ブログ:http ://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg = 1など)および本(専門家向けではありませんが、それでもhttp://en.highscore.de/cpp/boost/index.html)。Libuvにはオンラインブックが1冊しかありません(ただし、良い本もあります)http://nikhilm.github.com/uvbook/index.htmlいくつかのビデオトークがあるので、すべての秘密を知ることは難しいでしょう(このライブラリにはたくさんの秘密があります)。関数のより具体的な議論については、以下の私のコメントを参照してください。

結論として、それはすべてあなたの目的、あなたのプロジェクト、そしてあなたが具体的に何をしようとしているのかに依存していると言わなければなりません。

于 2012-10-30T12:27:15.747 に答える
23

大きな違いの1つは、Asio(Christopher Kohlhoff)の作成者がC++標準ライブラリに含めるためにライブラリをグルーミングしていることです。http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175を参照してください。 .pdfおよびhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html

于 2016-03-25T14:36:57.210 に答える
2

移植性ステータスの追加:この回答を投稿した時点で、私自身の試みによると:

  • Boost.ASIOはiOSとAndroidを公式にサポートしていません。たとえば、そのビルドシステムはそのままのiOSでは機能しません。
  • libuvは、iOSとAndroid向けに簡単にビルドでき、ドキュメントでAndroidを公式にサポートしています。Autotoolsベースのプロジェクト用の私自身の汎用iOSビルドスクリプトは問題なく動作します。
于 2019-10-20T04:14:00.290 に答える