2つのライブラリはどちらも非同期I / Oスケジューリング用に設計されており、どちらもLinuxではepoll、FreeBSDではkqueueなどを使用しています。
表面的な違いを除いて、これらの2つのライブラリの真の違いは何ですか?建築、またはデザイン哲学について?
2つのライブラリはどちらも非同期I / Oスケジューリング用に設計されており、どちらもLinuxではepoll、FreeBSDではkqueueなどを使用しています。
表面的な違いを除いて、これらの2つのライブラリの真の違いは何ですか?建築、またはデザイン哲学について?
回答:
設計哲学については、libevはlibeventのアーキテクチャ上の決定のいくつかを改善するために作成されました。たとえば、グローバル変数の使用はマルチスレッド環境でlibeventを安全に使用することを難しくしました。ウォッチャー構造は、I / O、時間、およびシグナルを組み合わせるため、大きくなります。ハンドラーが1つになっているため、httpサーバーやdnsサーバーなどの追加コンポーネントは、実装の品質が低く、その結果としてセキュリティの問題が発生し、タイマーが不正確で、時間のジャンプにうまく対応できませんでした。
Libevは、グローバル変数を使用せず、すべての関数にループコンテキストを使用して、イベントタイプごとに小さなウォッチャーを使用することにより、これらのそれぞれを改善しようとしました(I / Oウォッチャーは、libeventの136と比較して、x86_64で56バイトを使用します)。ウォールクロックと単調時間に基づくタイマー、スレッド間割り込み、他のイベントループを埋め込む、または埋め込むためのウォッチャーの準備とチェックなどのイベントタイプ。
余分なコンポーネントの問題はそれらをまったく持たないことで「解決」されるため、libevは小さくて効率的になる可能性がありますが、libevには単にそれがないため(たとえば、 libeioと呼ばれる非常に関連性の高いライブラリ。非同期I / Oを実行します。これは、独立して、またはlibevと一緒に使用できるため、組み合わせることができます)。
つまり、要するに、libevは1つのこと(POSIXイベントライブラリ)のみを実行しようとし、これを可能な限り最も効率的な方法で実行します。Libeventは完全なソリューションを提供しようとします(イベントlib、非ブロッキングI / Oライブラリ、httpサーバー、DNSクライアント)。
あるいは、もっと短いとすれば、libevは、1つのことだけを行うというUNIXツールボックスの哲学にできるだけ従うことを試みます。
これは設計哲学であり、私がlibevを設計したので、それを権威を持って述べることができることに注意してください。これらの設計目標が実際に達成されたかどうか、または哲学が健全な原則に基づいているかどうかは、判断する必要があります。
2017年更新:
タイマーの不正確さについて何度も尋ねられましたが、libevがWindowsのIOCPをサポートしていないのはなぜですか。
タイマーに関しては、libeventは知らないうちに将来のある未知の基準時間に関連してタイマーをスケジュールします。Libevは、タイマーをスケジュールするために使用するベース時間を事前に通知できます。これにより、プログラムはlibeventアプローチとlibevアプローチの両方を使用できます。さらに、バックエンドによっては、libeventがタイマーを早期に期限切れにすることがあります。前者はAPIの問題であり、後者は修正可能です(私はチェックしなかったため、修正されている可能性があります)。
IOCPのサポートについては、IOCPは十分に強力ではないため、実行できないと思います。1つには、ウィンドウに許可されるハンドルのセットをさらに制限する特別なソケットタイプが必要です(たとえば、perlで使用されるソケットはIOCPの「間違った」タイプです)。さらに、IOCPはI / O準備イベントをまったくサポートせず、実際のI / Oしか実行できません。ダミーの0バイトの読み取りなど、一部のハンドルタイプには回避策がありますが、これもまた、Windowsで使用できるハンドルタイプをさらに制限し、さらに、すべてのソケットプロバイダーで共有されていない可能性がある文書化されていない動作に依存します。 。
私の知る限り、他のイベントライブラリもWindowsのIOCPをサポートしていません。libeventが行うことは、イベントライブラリに加えて、IOCPを介して実行できる読み取り/書き込み操作をキューに入れることです。libevはI / Oを行わないため、libev自体でIOCPを使用する方法はありません。
これは確かに設計によるものです。libevは小さくPOSIXのようにしようとしますが、ウィンドウにはPOSIXスタイルのI / Oイベントを取得する効率的な方法がありません。IOCPが重要な場合は、自分で使用するか、実際にI / Oを実行してIOCPを使用できる他の多くのフレームワークを使用する必要があります。
libev
Windowsプラットフォームでは苦痛です。MinGWコンパイラは常に++activecnt
(関数ev_ref
)でsigfaultを実行し、私はこの問題を解決する方法を理解していません。2番目の問題はselect
、ソケットの相互運用の最新のIOCPバージョンで古いソケットインターフェイスを使用することです。Widnowsサポートを改善できますか?
私にとってのlibeventの大きな利点は、組み込みのOpenSSLサポートです。libevent APIの2.0バージョンで導入されたBuffereventインターフェイスは、開発者にとって安全な接続をほとんど苦痛なく処理します。私の知識が古くなっているかもしれませんが、libevはこれをサポートしていないようです。