In Bezug auf die Designphilosophie wurde libev entwickelt, um einige der Architekturentscheidungen in libevent zu verbessern. Beispielsweise machte es die Verwendung globaler Variablen schwierig, libevent in Multithread-Umgebungen sicher zu verwenden. Watcher-Strukturen sind groß, da sie E / A, Zeit und Signal kombinieren Handler in einem, die zusätzlichen Komponenten wie die http- und dns-Server litten unter schlechter Implementierungsqualität und daraus resultierenden Sicherheitsproblemen, und Timer waren ungenau und kamen mit Zeitsprüngen nicht gut zurecht.
Libev versuchte, diese zu verbessern, indem er keine globalen Variablen verwendete, sondern einen Schleifenkontext für alle Funktionen verwendete, indem er kleine Beobachter für jeden Ereignistyp verwendete (ein E / A-Beobachter verwendet 56 Bytes auf x86_64 im Vergleich zu 136 für libevent), was zusätzliche zuließ Ereignistypen wie Timer basierend auf Wanduhr vs. monotoner Zeit, Unterbrechungen zwischen Threads, Vorbereitung und Überprüfung von Beobachtern zum Einbetten anderer Ereignisschleifen oder zum Einbetten usw.
Das Problem mit zusätzlichen Komponenten wird "gelöst", indem sie überhaupt nicht vorhanden sind. Libev kann also klein und effizient sein, aber Sie müssen auch anderswo nach einer http-Bibliothek suchen, da libev einfach keine hat (zum Beispiel gibt es eine sehr verwandte Bibliothek namens libeio, die asynchrone E / A ausführt, die unabhängig oder zusammen mit libev verwendet werden kann, damit Sie mischen und anpassen können).
Kurz gesagt, libev versucht nur eines (POSIX-Ereignisbibliothek) und dies auf die effizienteste Art und Weise. Libevent versucht, Ihnen die vollständige Lösung zu bieten (Ereignisbibliothek, nicht blockierende E / A-Bibliothek, http-Server, DNS-Client).
Oder, noch kürzer, libev versucht, der UNIX-Toolbox-Philosophie zu folgen, nur eines so gut wie möglich zu tun.
Beachten Sie, dass dies die Designphilosophie ist, die ich mit Autorität angeben kann, weil ich libev entworfen habe. Ob diese Designziele tatsächlich erreicht wurden oder ob die Philosophie auf soliden Prinzipien basiert, liegt bei Ihnen.
Update 2017:
Ich wurde mehrmals gefragt, auf welche Timer-Ungenauigkeit ich verweise und warum libev IOCPs unter Windows nicht unterstützt.
Bei Timern plant libevent Timer relativ zu einer unbekannten Basiszeit, die in der Zukunft liegt, ohne dass Sie es wissen. Libev kann Ihnen im Voraus mitteilen, welche Basiszeit zum Planen von Timern verwendet wird, sodass Programme sowohl den Libevent-Ansatz als auch den Libev-Ansatz verwenden können. Darüber hinaus läuft libevent je nach Backend manchmal vorzeitig ab. Ersteres ist ein API-Problem, letzteres kann behoben werden (und wurde möglicherweise seitdem behoben - ich habe es nicht überprüft).
Was die IOCP-Unterstützung betrifft, denke ich nicht, dass dies möglich ist, da IOCPs einfach nicht leistungsfähig genug sind. Zum einen benötigen sie einen speziellen Socket-Typ, der die Anzahl der in Windows zulässigen Handles noch weiter einschränkt (z. B. sind die von Perl verwendeten Sopckets für IOCPs vom "falschen" Typ). Darüber hinaus unterstützen IOCPs überhaupt keine E / A-Bereitschaftsereignisse, sondern nur tatsächliche E / A. Es gibt Problemumgehungen für einige Handle-Typen, z. B. das Ausführen eines Dummy-0-Byte-Lesevorgangs. Dies würde jedoch die Handle-Typen, die Sie unter Windows verwenden können, noch weiter einschränken und sich außerdem auf undokumentiertes Verhalten stützen, das wahrscheinlich nicht von allen Socket-Anbietern gemeinsam genutzt wird .
Meines Wissens unterstützt auch keine andere Ereignisbibliothek IOCPs unter Windows. Libevent ermöglicht es Ihnen, zusätzlich zur Ereignisbibliothek Lese- / Schreibvorgänge in die Warteschlange zu stellen, die dann über IOCPs ausgeführt werden können. Da libev keine E / A für Sie ausführt, gibt es keine Möglichkeit, IOCPs in libev selbst zu verwenden.
Dies ist in der Tat beabsichtigt - libev versucht, klein und POSIX-ähnlich zu sein, und Windows bietet einfach keine effiziente Möglichkeit, E / A-Ereignisse im POSIX-Stil abzurufen. Wenn IOCPs wichtig sind, müssen Sie sie entweder selbst verwenden oder einige der vielen anderen Frameworks verwenden, die E / A für Sie ausführen und daher IOCPs verwenden können.