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