Soll eine Applikation Dienste auf Abruf bereitstellen, empfiehlt sich in der Regel der ereignisgesteuerte Programmierstil. Bei der schnellen Umsetzung helfen Bibliotheken, die die nötige Infrastruktur bereitstellen.
In der IT-Frühzeit arbeiteten alle Programme nach demselben Schema: Daten lesen, verarbeiten und Ergebnis ausgeben – eventuell in einer Schleife, die einen einfachen Dialogbetrieb erlaubte. Anwendungen mit grafischer Oberfläche, wie wir sie heute gewohnt sind, funktionieren nach einem anderen Prinzip: Jede Aktion des Nutzers, etwa ein Tastendruck oder Mausklick, löst einen bestimmten Event aus, auf den das Programm reagiert.
Um das Programmieren zu vereinfachen, bringen GUI-Toolkits in der Regel eine vorgefertigte „Event Loop“ mit, die die eingehenden Events auswertet und verteilt. Will die Anwendung von einem Ereignis erfahren, kann sie gewöhnlich einen Callback einrichten, der eine bestimmte Funktion aufruft, den sogenannten Event Handler, der alles Weitere erledigt. Das hat nicht zuletzt den Vorteil, dass das Programm modularer und damit überschaubarer wird.
Ereignisgesteuerte Programmierung lässt sich jedoch auch in Anwendungen ohne grafische Oberfläche sinnvoll einsetzen, etwa in einem Webserver. Will der Entwickler dafür nicht das Rad neu erfinden und seine eigene Event Loop stricken, kann er sich einschlägiger Frameworks bedienen. Von denen gibt es einige, mit unterschiedlichen Zielsetzungen: Mal steht die einfache Nutzung im Vordergrund, mal Portabilität oder hohe Performance. Für einfache Projekte in C++ eignet sich zum Beispiel die Bibliothek libasync (siehe iX-Link [a]). Statt normaler Callback-Funktionen verwendet sie vier überladbare virtuelle Methoden: OnRead(), OnWrite(), OnClose() und OnAccept(). Zwei separate Klassen, SocketConnection und DatagramConnection, erlauben die Nutzung von TCP und UDP als Transportmedium. Die Event Loop basiert auf dem Systemaufruf select. Leider ist der Code schon etwas älter und benötigt daher ein paar kleine Anpassungen, damit er sich mit aktuellen Compilern übersetzen lässt [b].
Etwas vielseitiger ist libivykis [c]. Die Bibliothek kann sowohl select und poll als auch die systemspezifischen Mechanismen /dev/poll (Solaris), kqueue (BSD) und epoll (Linux) verwenden. Letztere bieten bessere Performance, wenn die Anwendung viele Verbindungen gleichzeitig handhaben muss. Außer den Standard-Callbacks fürs Lesen und Schreiben von Daten gibt es einen dritten, der Fehler anzeigt – etwa den Abbruch der Verbindung. Zusätzlich kann der Programmierer Timer setzen, die zu einer vorgegebenen Zeit einen Callback auslösen. Zu den Nachteilen der Bibliothek zählt, dass der Nutzer einschlägige Systemaufrufe wie accept, connect, read oder write durch die bereitgestellten Wrapper-Funktionen ersetzen muss, damit sein Programm funktioniert.
libevent kann die Anwendung nicht nur benachrichtigen, wenn Daten zum Lesen bereitstehen, es kann sie selbst entgegennehmen und in einem sogenannten evbuffer speichern [d]. Callbacks zeigen an, dass der Füllstand bestimmte Markierungen über- oder unterschritten hat. Umgekehrt kann die Anwendung Daten in einen Sendepuffer legen, ohne sich um deren Versand kümmern zu müssen. Das erleichtert vor allem den Bau textorientierter Applikationen. Obendrein stellt libevent Routinen für den Aufbau eines einfachen Webservers, eines asynchronen DNS-Resolvers und RPC-basierter Dienste bereit, sodass sich der Entwickler unter Umständen viel Arbeit spart.
Die auf hohe Performance getrimmte Bibliothek lässt sich sowohl unter Linux/Unix als auch unter Windows nutzen. Da Letzteres eine vom Posix-Standard abweichende Schnittstelle zum Programmieren von Sockets verwendet, bringt libevent eine Reihe von Wrapper-Funktionen mit, die das Portieren von Anwendungen zwischen den beiden Welten erleichtern. Zwar zeichnet sich das Quelltext-Paket durch die Abwesenheit jeglicher Dokumentation aus. Eine ausführliche Programmieranleitung mit vielen Beispielen ist jedoch im Web zu finden [e].
libev [f] entstand als (noch) schnellere Alternative zu libevent und kann Letztere zu einem gewissen Grad emulieren – allerdings nur in der mittlerweile veralteten Version 1.4.1. Wer neue Software entwickelt, sollte jedoch die native Programmierschnittstelle der Bibliothek verwenden. Damit lassen sich Callbacks – im libev-Jargon „Watcher“ genannt – für diverse zusätzliche Ereignisse einrichten. Zum Beispiel kann libev unter Linux die Anwendung benachrichtigen, wenn sich die Attribute einer Datei ändern. Ein spezieller „Idle-Watcher“ teilt dem Programm mit, dass gerade keine Events zur Bearbeitung anstehen.
Wer nicht gern in C oder C++ programmiert, kann libev mit einem passenden Wrapper auch in Perl, Python, Ruby, Haskell, D, Ocaml oder Lua verwenden – allerdings nicht immer vollständig und in der aktuellen Version 4 [g-m]. Die Bibliothek sollte auf allen gängigen Linux/Unix-Systemen laufen, unter Windows lässt sie sich nur mit gewissen Einschränkungen verwenden; Näheres dazu verrät die ausführliche, aber leider recht lang geratene Manpage.
(mr)
Heft bestellen Dieser Text ist der Zeitschriften-Ausgabe 03/2011 von iX entnommen. Das Heft kann online portokostenfrei bestellt werden.
Version zum Drucken Per E-Mail versenden Newsletter abonnieren
Permalink: http://heise.de/-1192050
Mehr zum Thema Programmierung
iOS, Android, Windows Phone 7 und HTML5 - das neue Sonderheft von heise Developer führt Einsteiger und Profis in die Programmierung mobiler Geräte ein.