| 1 |
root |
1.1 |
=head1 Ereignisgesteuerte Programmierung mit Perl - die Realität |
| 2 |
|
|
|
| 3 |
|
|
=head2 Zusammenfassung |
| 4 |
|
|
|
| 5 |
|
|
Ereignisgesteuerte Programmierung ist hinreichend bekannt. Trotzdem |
| 6 |
|
|
wird sie relativ selten benutzt - in Modulen so gut wie garnicht. Ich |
| 7 |
|
|
möchte hier verschiedene Arten der Ereignissteuerung sauber von anderen |
| 8 |
|
|
Formen der Programmierung zu trennen, vorhandene Ereignismodule und ihre |
| 9 |
|
|
Unterschiede vorstellen. Vor allem sollen Möglichkeiten gezeigt werden, |
| 10 |
|
|
wie man als Modulautor - je nach gewünschtem Aufwand - verschiedene APIs |
| 11 |
|
|
anbieten kann. |
| 12 |
|
|
|
| 13 |
root |
1.2 |
|
| 14 |
|
|
=head1 Ereignissteuerung - In aller Kürze |
| 15 |
|
|
|
| 16 |
|
|
Ereignissteuerung ist - für mich - kein sehr exakt festgelegter Begriff |
| 17 |
|
|
oder eine festgelegte Syntax. Daher will ich einige Beispiele für |
| 18 |
|
|
verschiedene Arten bzw. Grade der Ereignissteuerung, wie sie in der Praxis |
| 19 |
|
|
vorkommen. |
| 20 |
|
|
|
| 21 |
|
|
Üblicherweise verwendet man Ereignissteuerung immer dann, wenn man |
| 22 |
|
|
genügend Rechenzeit für die Verarbeitung vieler Aufgaben hat, jedoch durch |
| 23 |
|
|
externe Umstände (I/O-Geschwindigkeit, Netzwerk, User klickt nicht schnell |
| 24 |
|
|
genug :) gezwungen ist, auf Daten bzw. Ereignisse zu warten. |
| 25 |
|
|
|
| 26 |
|
|
Ereignissteuerung bedeutet dann, ein Programm derart zu strukturieren, |
| 27 |
|
|
daß es auf Ereignisse wartet und - möglichst schnell - reagiert. Die |
| 28 |
|
|
Haupt-Eingabe besteht sozusagen in einem Strom von Ereignissen |
| 29 |
|
|
(Event-Stream). |
| 30 |
|
|
|
| 31 |
|
|
Unter Unix gibt es eine zentrale Funktion, mit dem ein Programm auf |
| 32 |
|
|
Ereignisse warten kann: C<select> (bzw. auch C<pselect>/C<poll>, die sich |
| 33 |
|
|
aber nicht von C<select> unterscheiden, sowie kompliziertere Methoden wie |
| 34 |
|
|
realtime-Signale, die aber alle auf dasselbe hinauslaufen). C<select> kann |
| 35 |
|
|
auf einen Timeout und auf die Möglichkeit, auf einen Filehandle schreiben |
| 36 |
|
|
oder davon lesen zu können, warten. Dies reicht für alles aus, da unter |
| 37 |
|
|
Unix "alles ein Dateihandle ist" (und wenn dies einmal nicht der Fall ist, |
| 38 |
|
|
ist das gleich ein major pain in the ass und man tut gut daran, es auf |
| 39 |
|
|
einen Dateihandle abzubilden). |
| 40 |
|
|
|
| 41 |
|
|
Daher ist eine derartige Programmstruktur meist eine zentrale Schleife, |
| 42 |
|
|
in der auf Ereignisse (definiert durch "Watcher") gewartet wird und |
| 43 |
|
|
dann Funktionen aufgerufen werden, um auf diese Ereignisse zu reagieren |
| 44 |
|
|
("Callbacks"). Da C<select> etwas low-level ist, gibt es Bibliotheken |
| 45 |
|
|
und Module, die diese Funktionalität in eine freundlichere Schnittstelle |
| 46 |
|
|
gießen - das nennt man dan "Event-Modell". |
| 47 |
|
|
|
| 48 |
|
|
Daraus folgt, daß das "Hauptprogramm" der Aufruf dieser Schleife/dieses |
| 49 |
|
|
Event-Modells ist, und alle Ereignisse in Unterfunktionen behandelt werden |
| 50 |
|
|
müssen. Daher lassen sich in einem Programm auch sehr schwer meherre |
| 51 |
|
|
Event-Modelle miteinander mischen, da nur jeweils eines die Kontrolle über |
| 52 |
|
|
den Programmablauf haben kann. |
| 53 |
|
|
|
| 54 |
|
|
|
| 55 |
root |
1.1 |
|
| 56 |
|
|
=head2 Nicht Ereignisgesteuert |
| 57 |
|
|
|
| 58 |
|
|
=head3 blocking vs. blocking |
| 59 |
|
|
|
| 60 |
|
|
=head2 Continuation Passing |
| 61 |
|
|
|
| 62 |
|
|
=head2 Coroutinen/Threads |
| 63 |
|
|
|
| 64 |
|
|
|
| 65 |
|
|
=head1 Event-Modelle |
| 66 |
|
|
|
| 67 |
|
|
=head2 Event |
| 68 |
|
|
|
| 69 |
|
|
=head2 Glib/Gtk2, Tk, |
| 70 |
|
|
|
| 71 |
|
|
=head2 Coroutinen - Coro::AIO |
| 72 |
|
|
|
| 73 |
|
|
|
| 74 |
|
|
=head1 Das Problem für Modulautoren |
| 75 |
|
|
|
| 76 |
|
|
|
| 77 |
|
|
=head1 Lösungen/Workarounds |
| 78 |
|
|
|
| 79 |
|
|
=head2 Wozu? Blocking reicht - LWP |
| 80 |
|
|
|
| 81 |
|
|
=head2 Überlass es dem User - Net::Knuddels, IO::AIO |
| 82 |
|
|
|
| 83 |
|
|
=head2 Leg dich fest - Coro::Event |
| 84 |
|
|
|
| 85 |
|
|
=head2 Bilde ein Modell auf ein anderes ab - Glib::Event |
| 86 |
|
|
|
| 87 |
|
|
=head2 Threads - ??? |
| 88 |
|
|
|
| 89 |
|
|
=head2 AnyEvent - Coro::AIO, Net::FCP |
| 90 |
|
|
|
| 91 |
|
|
|
| 92 |
root |
1.2 |
=head1 Fallbeispiel Modul-API: Net-FCP und AnyEvent |
| 93 |
root |
1.1 |
|
| 94 |
root |
1.2 |
=head2 Benutzung |
| 95 |
root |
1.1 |
|
| 96 |
root |
1.2 |
=head2 Implementation |
| 97 |
root |
1.1 |
|