ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/docs/pws2002/coro.sdf
Revision: 1.2
Committed: Wed Jan 16 03:23:37 2002 UTC (24 years, 9 months ago) by root
Branch: MAIN
Changes since 1.1: +523 -100 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 !init OPT_STYLE="paper"
2    
3     !define DOC_NAME "Coroutinen und Continuations mit dem Coro-Modul"
4     !define DOC_AUTHOR "Marc Lehmann <pcg@goof.com>"
5     !build_title
6    
7 root 1.2 H1: Was sind Coroutinen und Continuations?
8    
9     Prozedurale Programme laufen normalerweise sequentiell ab und springen
10     manchml in Unterprogramme/Funktionen. Es ist nicht möglich, aus einem
11     Unterprogramm heraus kurzzeitig in den Aufrufer zurückzuspringen und später
12     an gleicher Stelle weiterzuarbeiten.
13    
14     Dies liegt daran, daß Perl, wie viele andere Sprachen, Funktionsaufrufe
15     mit einem Stack implementieren, den man in der gleichen Reihenfolge
16     abbauen muss, wie man ihn aufbaut.
17    
18     Continuations abstrahieren diesen Stack, d.h. es gibt nicht nur eine
19     Aufruffolge sondern viele. Zwischen diesen kann an beliebigen Stellen
20     gewechselt werden. Exception-handling, nichtlokale Sprünge, Multitasking
21     und Threads können mit Continuations implementiert werden.
22    
23     Coroutinen sind eine Anwendung von Continuations, bei denen meherere
24     unabhängige Ablaufinstanzen nacheinander kurzzeitig ausgeführt werden, so
25     daß der Eindruck von gleichzeitigem Ablauf entstehen kann (kooperatives
26     Multitasking). Der Unterschied zu Continuations ist im wesentlichen der,
27     daß der Wechsel normalerweise nicht explizit erfolgt und keine Parameter
28     zwischen den Instanzen ausgetauscht werden, da die Reihenfolge nicht
29     festgelegt ist.
30    
31 root 1.1 H1: Die Entstehung des Coro-Moduls
32    
33 root 1.2 Continuations für Perl5 stehen seit ca. 1996 auf meinem "TODO"-Zettel,
34     aber da ich immer dachte, es wäre viel zu langsam (Kopieren des gesamten
35 root 1.1 Stacks oder schlimmer?) und kompliziert, um jemals implementiert zu
36     werden.
37    
38     H1: Das Problem
39    
40     Um Coroutinen zu implementieren, reicht es, zwei Primitiven zu schreiben
41     (die Namen stammen aus Modula-2, die Perl-Syntax sieht etwas anders aus):
42    
43     NEWPROCESS(process,coderef)
44     TRANSFER(oldprocess,newprocess)
45    
46     C<NEWPROCESS< erzeugt einen neuen "Prozess", wobei ein "Prozess" im
47     wesentlichen einen Aufrufstack (zum Schachteln von Funktionsaufrufen)
48     und einen Startpunkt (C<coderef>) besitzt. Diese Daten werden in einer
49     Struktur (C<process>) abgelegt.
50    
51 root 1.2 Um einen solchen Prozess zu starten muß man die Kontrolle an ihn abgeben,
52 root 1.1 indem man C<TRANSFER> mit einer leeren C<process>-Struktur als erstes
53 root 1.2 Argument und einer gültigen (z.b. von C<NEWPROCESS>) C<process>-Struktur
54 root 1.1 als zweites Argument aufruft.
55    
56     C<TRANSFER> sichert nun die Daten des {{aktuellen}} Prozesses in
57     C<oldprocess> und "springt" in den neuen.
58    
59     Damit lassen sich Continuations und kooperatives und preemptives
60 root 1.2 Multitasking implementieren, wenn man es zu nutzen weiß.
61 root 1.1
62     H1: Teil 1: Implementation
63    
64     H2: Erste Erfolge und erste Probleme
65    
66     Im Juli 2001 war es dann so weit: in einem Anflug von Leichtsinn dachte
67 root 1.2 ich mir, "ein paar Pointer-Austauscher könnten doch zum Ziel führen".
68 root 1.1
69 root 1.2 (Es folgen einige Haarsträubende Implementationsdetails, wer will, kann
70     die überspringen und direkt zum interessanten Teil übergehen ;)
71 root 1.1
72 root 1.2 Und tatsächlich, wenige Stunden (und Zeilen) später hatte ich ein Modul,
73     daß die beiden obigen Primitiven implementiert. Es funktionierte sogar:
74 root 1.1
75     !block "C"
76     save_state(pTHX_ Coro__State c, int flags)
77     {
78     c->curstackinfo = PL_curstackinfo;
79     c->curstack = PL_curstack;
80     c->mainstack = PL_mainstack;
81     c->stack_sp = PL_stack_sp;
82     c->op = PL_op;
83     ...
84     c->curcop = PL_curcop;
85     c->top_env = PL_top_env;
86     }
87    
88     load_state(pTHX_ Coro__State c)
89     {
90     PL_curstackinfo = c->curstackinfo;
91     PL_curstack = c->curstack;
92     PL_mainstack = c->mainstack;
93     PL_stack_sp = c->stack_sp;
94     PL_op = c->op;
95     ...
96     PL_curcop = c->curcop;
97     PL_top_env = c->top_env;
98     }
99     !endblock
100    
101     Bis einmal zwei Coroutinen dieselbe Funktion aufriefen. Viele
102 root 1.2 Stunden später kam dann das "Aha! So macht Perl das also. Na so ein
103 root 1.1 Mist...". Leider reicht es nicht, einfach die vielen Stacks auszutauschen,
104     die Perl benutzt. Denn Perl modifiziert bei jedem Aufruf einer Funktion
105     die Funktion (genauer: den CV) selbst:
106    
107     !block "C"
108     /* aus pp_entersub */
109     CvDEPTH(cv)++;
110     if (CvDEPTH(cv) < 2)
111     (void)SvREFCNT_inc(cv);
112     else { /* save temporaries on recursion? */
113     PERL_STACK_OVERFLOW_CHECK();
114     if (CvDEPTH(cv) > AvFILLp(padlist)) {
115     /* hier wird eine neue padlist erzeugt - 40 Zeilen Magie */
116     ...
117     }
118     }
119     ...
120     PL_curpad = AvARRAY((AV*)svp[CvDEPTH(cv)]);
121     !endblock
122    
123 root 1.2 Da wurde mir auch klar, weshalb Threads so langsam sind, denn die müssen
124 root 1.1 unglaubliche Anstrengungen unternehmen, damit sich einzelne Threads nicht
125     in die Queue kommen. C<pp_entersub> ist alles andere als trivial, ein
126 root 1.2 Wunder, daß Perl so schnell ist.
127 root 1.1
128 root 1.2 Im wesentlichen geht es darum, für jede Rekursionsstufe eine C<padlist>
129     (in der werden lokale Variablen u.ä. gespeichert) zu erzeugen, wobei die
130 root 1.1 erste schon beim Kompilieren erzeugt wird.
131    
132     Solange eine Coroutine nicht in eine Funktion springt, die schon rekursiv
133     aufgerufen wurde, ist das kein Problem, da CvDEPTH dann 1 ist und die
134 root 1.2 erste padlist leer. Andernfalls wird die Rekursionsstufe erhöht, auch
135 root 1.1 kein Problem. Wenn die erste Coroutine dann aber wieder aus der Funktion
136 root 1.2 zurückkehren will, gibt es ein Problem, denn das käme dem Problem
137     gleich, die n-te Rekursionsstufe zu beenden während die n+1-te nich immer
138 root 1.1 aktiv ist.
139    
140 root 1.2 Die Lösung ist eklig, aber noch nicht unzumutbar langsam: Da ein
141     Perl-Modul nicht die Freiheit hat, C<pp_entersub> zu verändern (die
142 root 1.1 Perl-Thread-Implementation kann sich das leisten), muss der Aufrufstack
143 root 1.2 hinaufgewandert werden und manuell eine Art "Rücksprung" organisiert werden:
144 root 1.1
145     !block "C"
146     save_state(pTHX_ Coro__State c, int flags)
147     ...
148     /* this loop was inspired by pp_caller */
149     for (;;)
150     {
151     while (cxix >= 0)
152     {
153     PERL_CONTEXT *cx = &ccstk[cxix--];
154    
155     if (CxTYPE(cx) == CXt_SUB)
156     {
157     CV *cv = cx->blk_sub.cv;
158     if (CvDEPTH(cv))
159     {
160     EXTEND (SP, CvDEPTH(cv)*2);
161    
162     while (--CvDEPTH(cv))
163     {
164     /* this tells the restore code to increment CvDEPTH */
165     PUSHs (Nullsv);
166     PUSHs ((SV *)cv);
167     }
168    
169     PUSHs ((SV *)CvPADLIST(cv));
170     PUSHs ((SV *)cv);
171    
172     get_padlist (cv); /* this is a monster */
173     }
174     }
175     ...
176     if (top_si->si_type == PERLSI_MAIN)
177     break;
178    
179     top_si = top_si->si_prev;
180     ccstk = top_si->si_cxstack;
181     cxix = top_si->si_cxix;
182     }
183     ...
184    
185     load_state(pTHX_ Coro__State c)
186     ...
187     /* now do the ugly restore mess */
188     while ((cv = (CV *)POPs))
189     {
190     AV *padlist = (AV *)POPs;
191    
192     if (padlist)
193     {
194     put_padlist (cv); /* mark this padlist as available */
195     CvPADLIST(cv) = padlist;
196     }
197    
198     ++CvDEPTH(cv);
199     }
200     !endblock
201    
202     Der lustigste Teil verbirgt sich hinter:
203    
204     get_padlist (cv); /* this is a monster */
205    
206 root 1.2 Denn, während man die neu erzeugten padlists einfach wegsichern kann,
207     muss die erste neu erzeugt werden, ein höchst umständlicher Vorgang, der
208 root 1.1 deshalb auch (mit einem Hash) gecached wird.
209    
210 root 1.2 Damit war bewiesen, daß Coroutinen tatsächlich so viele Probleme machen,
211     wie ich befürchtet hatte.
212 root 1.1
213 root 1.2 H2: Das vorläufige Ende
214 root 1.1
215     Aber es kam noch schlimmer. Beispiel: Perl ruft eine XS-Funktion auf, und
216 root 1.2 diese wieder einen Perl-Callback. Dieser führt einen Coroutinenwechsel
217 root 1.1 durch und die neue Coroutinen macht ein C<return> - wohin? In die
218 root 1.2 XS-Funktion, die natürlich Ergebnisse auf dem Stack erwartet, die
219     natürlich nicht da sind. dies ist auch der Grund dafür, daß der "fake
220     threads"-Ansatz von Perl (vorerst) zum Scheitern verurteilt ist.
221 root 1.1
222     An diesem Punkt habe ich erstmal aufgegeben. Die Aussicht, auch eine
223 root 1.2 portable Coroutinenimplementation für C zu finden, waren Null, sie werden
224     ja noch nicht einem in irgendwelchen Standards erwähnt (dachte ich).
225 root 1.1
226 root 1.2 Naja, selbst schreiben war angesagt - tatsächlich kann man, lediglich
227 root 1.1 mit UNIX95-Funktionen, portabel Coroutinen erzeugen. Leider ist mir
228 root 1.2 kein System bekannt, daß sich wirklich an den Standard hielte (von
229 root 1.1 Grausamkeiten wie IRIX mal ganz abgesehen, dessen Programmierer vom
230     Programmieren herzlich wenig Ahnung haben (siehe sigaltstack, das
231     vollkommen dokumentiert das vollkommen sinnlose macht)), aber die
232 root 1.2 Unterschiede sind gering. Sogar unter der eingeschränkten Win32-API
233 root 1.1 kann man durch direktes herumpoken in C<jmp_buf> relativ schmerzlos eine
234     Implementation bekommen.
235    
236     Im Coro-Modul gibt es im Verzeichnis C<Coro/libcoro> seitdem eine
237     relativ portable, sehr kleine (366 Zeilen inkl. Dokumentation ;)
238 root 1.2 Coroutinenimplementation für C.
239 root 1.1
240 root 1.2 Das Coro-Modul erzeugt entweder für jede Coroutine in Perl eine Coroutine
241 root 1.1 in C, oder optional nur "on demand", d.h. wenn sich der C-Stackpointer
242 root 1.2 verändert hat, eine gefährliche, aber in der Praxis gut funktionierende
243 root 1.1 Heuristik.
244    
245     H1: Teil 2: Implementation von Coroutinen und Continuations in Perl
246    
247     H2: Die Perl-API
248    
249     C<NEWPROCESS> und C<TRANSFER> werden vom C<Coro::State>-Modul implementiert.
250     C<NEWPROCESS> sieht in Perl so aus:
251    
252     !block "perl"
253 root 1.2 # eine "leere" Coroutine, bereit, gefüllt zu werden
254 root 1.1 $main = new Coro::State;
255    
256     # eine neue Coroutine, zu der man wechseln kann
257     $new = new Coro::State sub {
258     # ... coroutine
259     }, @args;
260     !endblock
261    
262     Und C<TRANSFER> sieht so aus:
263    
264     !block "perl"
265     # etwas asymetrisch:
266     $main->transfer($new);
267     # oder symmetrischer
268     Coro::State::transfer($main,$new);
269     !endblock
270    
271     H2: Continuations
272    
273 root 1.2 Nicht, daß ich das Modul viel benutzen würde, aber ich wollte zeigen,
274     daß es geht: Das C<Coro::Cont>-Modul exportiert zwei Funktionen, C<csub>,
275 root 1.1 mit dem sich neue Continuations erzeugen lassen und C<yield>, das so
276 root 1.2 ähnlich wie C<return> wirkt. Ausserdem werden Attribute unterstützt, so,
277     daß man Continuations so schreiben kann:
278 root 1.1
279     !block "perl"
280     use Coro::Cont;
281    
282     sub generator : Cont {
283     my $state = time;
284     while() {
285     $state = $state * 31231 % 65531;
286     yield $state % $_[0];
287     }
288     }
289     !endblock
290    
291     Beim ersten Aufruf wird der Zustand initialisiert, bei jedem weiteren
292     Aufruf wird eine (schlechte) Zufallszahl im Bereich C<0..$_[0]>
293 root 1.2 zurückgeliefert, wobei @_ sich jedesmal ändert. Das Attributsystem von
294     Perl5 ist ziemlich schwer zu benutzen (mehrere Module können es sich
295 root 1.1 nicht einfach teilen, Attribute sind automatisch global etc..), weshalb
296 root 1.2 ich darauf nicht näher eingehe ;)
297 root 1.1
298     Die Implementation ist einigermassen trickreich, da die Standardimplementation
299 root 1.2 von C<transfer> das Array C<@_> mitspeichert, es also nicht so einfach übergeben
300 root 1.1 werden kann. Deshalb kann man C<transfer> ein drittes Argument, eine Bitmaske
301 root 1.2 mit Flags, übergeben, die angibt, ob C<@_> oder C<$_> u.ä. Teil des
302 root 1.1 "Prozesszustandes" werden oder nicht.
303    
304 root 1.2 C<csub> erzeugt zwei C<Coro::State>-Objekte, eines für den Aufrufer und eines
305     für die Continuation:
306 root 1.1
307     !block "perl"
308     sub csub(&) {
309     my $code = $_[0];
310     my $prev = new Coro::State;
311    
312     my $coro = new Coro::State sub {
313     # we do this superfluous switch just to
314     # avoid the parameter passing problem
315     # on the first call
316     &yield;
317     &$code while 1;
318     };
319     !endblock
320    
321     D.h. die Kode-Referenz wird in einer Schleife aufgerufen. Da die Parameter
322 root 1.2 beim ersten Aufruf der Coroutine etwas anders übergeben werden als
323     später bei C<yield> wird als erstes ein C<yield> ausgeführt, damit alle
324 root 1.1 Aufrufe identisch sind.
325    
326 root 1.2 Als nächstes wird die neu erzeugte Coroutine {{einmal}} aufgerufen (damit
327 root 1.1 sie "yield"-en kann):
328    
329     !block "perl"
330     push @$$return, [$coro, $prev];
331     &Coro::State::transfer($prev, $coro, 0);
332     !endblock
333    
334     In der gobalen Variablen C<$return> befindet sich eine eine Referenz
335 root 1.2 auf ein Array, in dem die "Rücksprung"-Coroutinen gespeichetr sind,
336 root 1.1 d.h. C<Coro::Cont> macht fast den gleichen "Fehler" wie C<pp_entersub>,
337     aber C<$$return> ist nicht wirklich global (wie ich gleich zeige ;)
338    
339 root 1.2 Als letztes wird eine Kode-Referenz zurückgegeben, die das Aufrufen der
340     Coroutine für uns erledigt:
341 root 1.1
342     !block "perl"
343     return sub {
344     push @$$return, [$coro, $prev];
345     &Coro::State::transfer($prev, $coro, 0);
346     wantarray ? @_ : $_[0];
347     };
348     !endblock
349    
350 root 1.2 Auch hier wird die "Rücksprungaddresse" für C<yield> in C<@$$return>
351     gespeichert und dann die Coroutine aufgerufen, die beim nächsten C<yield>
352     zurückkehrt. Die Argumente, die die Coroutine an C<yield> übergeben hat,
353 root 1.1 stehen immer noch in C<@_>.
354    
355     Die Funktion C<yield> ist in XS implementiert, die
356     Prototyp-Implementation in Perl sah jedoch so aus:
357    
358     !block "perl"
359     sub yield(@) {
360     &Coro::State::transfer(@{pop @$$return}, 0);
361     wantarray ? @_ : $_[0];
362     }
363     !endblock
364    
365 root 1.2 Auch nichts überraschendes, es wird zum Aufrufer zurückgegeben. Beim
366     nächsten Aufruf wird das neue C<@_> zurückgegeben, d.h. der Aufruf
367     müsste lauten: C<@_ = yield ...>, und das ist der Grund, weshalb es
368 root 1.1 in XS implementiert wurde, denn in XS kann man das C<@_> des Aufrufers
369 root 1.2 verändern. Wäre nicht dieser Umstand. so würde auch C<yield> in reinem
370 root 1.1 Perl implementiert sein.
371    
372 root 1.2 Das verbleibende Problem ist die globale Variable C<$return>. Tatsächlich
373 root 1.1 ist sie ein C<Coro::Specific>-Objekt und ist "Coroutinen"spezifisch, d.h.
374     kann in jeder Coroutine (hier meine ich ein C<Coro>-Objekt und nicht das
375     C<Coro::State>-Objekt) einen anderen Wert besitzen.
376    
377     H2: C<Coro::Specific>
378    
379     Mit C<Coro::State> kann man eigene Prozess-Abstraktionen basteln. Damit
380 root 1.2 C<Coro::Specific> funktioniert, muß man lediglich einen
381 root 1.1 coroutinen-/prozessspezifischen Hash in C<$Coro::current> speichern, und
382     genau das macht das C<Coro>-Modul.
383    
384 root 1.2 C<Coro::Specific->new> gibt eine Referenz auf einen ge'tie'ten Scalar zurück, der
385 root 1.1 wiederum bei C<FETCH> und C<STORE> einen Skalar im Array
386 root 1.2 C<@{$Coro::current->{specific}}> verändert. Solange das C<Coro>-Modul nicht
387 root 1.1 geladen ist, istd as immer derselbe, danach ist er coroutinenspezifisch.
388    
389     !block "perl"
390     my $idx;
391    
392     sub new {
393     my $var;
394     tie $var, Coro::Specific::;
395     \$var;
396     }
397    
398     sub TIESCALAR {
399     my $idx = $idx++;
400     bless \$idx, $_[0];
401     }
402    
403     sub FETCH {
404     $Coro::current->{specific}[${$_[0]}];
405     }
406    
407     sub STORE {
408     $Coro::current->{specific}[${$_[0]}] = $_[1];
409     }
410     !endblock
411    
412     Auf diese Weise kann man in anderen Modulen ohne schlechtes Gewissen
413     C<Coro::Specific> verwenden, da weder C<Coro::State> noch C<Coro> geladen
414 root 1.2 sein müssen.
415 root 1.1
416     H2: Prozesse selbst gemacht
417    
418 root 1.2 Der nächste Schritt, nach Continuations, Variablen und (primitiven)
419 root 1.1 Coroutinen sind richtige Prozesse. Diese werden im C<Coro>-Modul
420 root 1.2 implementiert, daß Prozesserzeugung, Kommunikation, Prioritäten etc.
421 root 1.1 anbietet.
422    
423     Das sieht dann so aus:
424    
425     !block "perl"
426     use Coro:
427    
428     async {
429     # ein neuer "Prozess"
430     };
431    
432     my $coro = async {
433     terminate;
434     };
435    
436     $coro->prio(PRIO_MAX);
437     $coro_>join;
438    
439 root 1.2 cede; # gib die CPU frei für andere Prozesse
440 root 1.1
441     # usw.. hat ja "jeder" schon mal gesehen ;-]
442     !endblock
443    
444     Die Implementation ist in einigen Teilen in XS, der Geschwindigkeit
445     wegen. Wenn das Modul geladen wird, erzeugt es zuerst einen
446 root 1.2 "Hauptprozess", der für das Hauptprogramm steht (das Hauptprogramm
447 root 1.1 korrekt auf eine Coroutine abzubilden ist sowieso ein sehr schwieriges
448     Unterfangen - welche Coroutine DESTROY't die anderen Coroutinen am
449 root 1.2 Programmende, wenn das Hauptprogramm nicht mehr existiert?) und sorgt für
450     die Übernahme des bisherigen C<@{$Coro::current->{specific}}>.
451 root 1.1
452     !block "perl"
453     our $main = new Coro;
454    
455     # maybe some other module used Coro::Specific before...
456     if ($current) {
457     $main->{specific} = $current->{specific};
458     }
459    
460     our $current = $main;
461     !endblock
462    
463 root 1.2 Dann folgt die Erzeugung eines Idle-Prozesses, der Rechenzeit verbrät wenn kein
464     Prozess mehr läuft:
465 root 1.1
466     !block "perl"
467     our $idle = new Coro sub {
468     print STDERR "FATAL: deadlock detected\n";
469     exit(51);
470     };
471     !endblock
472    
473 root 1.2 Jaja, reingefallen. Wenn kein Prozeß mehr am laufen ist, haben wir einen
474     Deadlock, zumindest, solange man Signale außer acht läßt. Das ändert
475 root 1.1 sich, wenn man Events benutzt (z.B. mit C<Coro::Event>), weshalb der
476     Idle-Prozess auswechselbar ist.
477    
478     Neue Prozesse werden mit C<async> oder C<Coro->new> erzeugt:
479    
480     !block "perl"
481     sub _newcoro {
482     terminate &{+shift};
483     }
484    
485     sub new {
486     my $class = shift;
487     bless {
488     _coro_state => (new Coro::State $_[0] && \&_newcoro, @_),
489     }, $class;
490     }
491    
492     sub async(&@) {
493     my $pid = new Coro @_;
494     $manager->ready; # this ensures that the stack is cloned from the manager
495     $pid->ready;
496     $pid;
497     }
498     !endblock
499    
500     Ein Prozess ist also wenig mehr als nackter Hash, in dessen
501 root 1.2 C<_coro_state>-Slot ein C<Coro::State>-Objekt gespeichert ist. Ähnlich
502 root 1.1 wie PDL sieht C<transfer> in diesem Slot nach einem C<Coro::State>-Objekt.
503    
504 root 1.2 Interessanter ist, daß C<async> den C<$manager> in Bereitschaft versetzt
505     und nicht nur den neuen Prozess. Der einzige Grund dafür ist, daß so die
506 root 1.1 meisten Prozesse mit einem definierten Stackpointer erzeugt werden, so
507 root 1.2 daß derselbe C-Stack für alle Prozesse verwendet werden kann, zumindest
508     anfänglich.
509 root 1.1
510     Am Ende eines Prozesslebens steht ein C<terminate>, oder ein C<cancel>:
511    
512     !block "perl"
513     sub cancel {
514     push @destroy, $_[0];
515     $manager->ready;
516     &schedule if $current == $_[0];
517     }
518     !endblock
519    
520 root 1.2 C<schedule> springt direkt in den Scheduler, der den nächsten
521     lauffähigen Prozess aus der Warteschlange nimmt und zum aktuellen
522 root 1.1 macht. Er ist (jaja, "the need for speed") in XS implementiert, sieht aber
523 root 1.2 in etwa (keine Prioritäten) so aus:
524 root 1.1
525     !block "perl"
526     sub schedule {
527     my $previous = $current;
528     $current = shift @runqueue;
529     Coro::State::transfer($current, $previous);
530     }
531     !endblock
532    
533     Der aktuelle Prozess wird nicht automatishc wieder aufgerufen, dazu muss
534     man ihn wieder mit der C<ready>-Methode in die Warteschlange setzen. Um
535 root 1.2 nur kurz andere Prozesse laufen zu lassen konnte man früher C<yield>
536     benutzen, aber das ging schon für Continuations drauf, und Damian Conway
537 root 1.1 fand das wichtiger, also musste ich einen neuen Namen finden:
538    
539     !block "perl"
540     sub cede {
541     $current->ready;
542     schedule;
543     }
544     !endblock
545    
546 root 1.2 Einen Prozess direkt zu zerstören, ist keine gute Idee. Zum einen könnte
547 root 1.1 er mehrfach in der C<ready>-Queue stehen, zum anderen sollte ein Prozess
548 root 1.2 sich selbst C<DESTROY>en können, aber da er sich dabei selbst den C-Stack
549 root 1.1 wegzieht, muss dies von einem anderen Prozess aus stattfinden. Der
550 root 1.2 Manager-Prozess stellt genau dies sicher (und verständig auch gleich
551 root 1.1 eventuell wartende Prozesse):
552    
553     !block "perl"
554     my @destroy;
555     my $manager;
556     $manager = new Coro sub {
557     while() {
558     # by overwriting the state object with the manager we destroy it
559     # while still being able to schedule this coroutine (in case it has
560     # been readied multiple times. this is harmless since the manager
561     # can be called as many times as neccessary and will always
562     # remove itself from the runqueue
563     while (@destroy) {
564     my $coro = pop @destroy;
565     $coro->{status} ||= [];
566     $_->ready for @{delete $coro->{join} || []};
567     $coro->{_coro_state} = $manager->{_coro_state};
568     }
569     &schedule;
570     }
571     };
572     !endblock
573    
574     H2: Signale, Semaphoren, Channels und Locks
575    
576     Hat man Prozesse, die man erzeugen, anhalten, schedulen und wieder beenden
577     kann, so muss man sie koordinieren. Zum Beispiel mit C<Coro::Signal>'s:
578    
579     !block "perl"
580     sub send {
581     if (@{$_[0][1]}) {
582     (shift @{$_[0][1]})->ready;
583     } else {
584     $_[0][0] = 1;
585     }
586     }
587    
588     sub wait {
589     if ($_[0][0]) {
590     $_[0][0] = 0;
591     } else {
592     push @{$_[0][1]}, $Coro::current;
593     Coro::schedule;
594     }
595     }
596     !endblock
597    
598 root 1.2 Getreu dem Motto "Pseudo-Hashes müssen sterben!", etwas ungewöhnlich
599 root 1.1 ausgelegt, verwendet C<Coro::Signal> ein Array und keinen Hash. Das erste
600     element ist nur ein Flag, das angibt, ob das Signal gesendet wurde (falls
601     niemand darauf wartet). Das zweite Element ist ein Array von wartenden
602     Prozessen.
603    
604     C<send> weckt den ersten wartenden Prozess auf oder - falls es keinen gibt
605 root 1.2 - setzt das Flag. Wenn man auf ein Signal wartet, wird zuerst geprüft, ob
606 root 1.1 es schon aufgetreten ist, ansonsten reiht sich der aktuelle Prozess in die
607     Warteschlange und legt sich schlafen.
608    
609     H1: Teil 3: Die Aussenwelt
610    
611 root 1.2 H2: C<Event> für Coro: C<Coro::Event>
612    
613     Multitasking innerhalb von Perl ist ja ganz nett, aber das erste
614    
615     !block "perl"
616     my $line = <STDIN>;
617     !endblock
618    
619     bringt das ganze System zum Erliegen. Wenn man viele asynchrone
620     Ein-/Ausgabekanäle hat die in unterschiedlicher Reihenfolge bedient
621     werden sollen, braucht man eine Ereignissteuerung. Das Standardmodul für
622     diesen Fall ist das (leider nicht mehr maintainte und auf vielen Systemen
623     nicht mehr lauffähige) Event-Modul, das jedoch Callback erfordert.
624    
625     Das C<Coro::Event>-Modul benutzt Event (oder ein anderes Modul, es gibt
626     nur keines ;), statt einem Callback wird der Prozess solange blockiert,
627     bis das Ereignis eintritt:
628    
629     !block "perl"
630     my $event = Coro::Event->timer(after => 1, interval => 1, hard => 1);
631    
632     while() {
633     $event->next;
634     print "one event every second\n";
635     }
636     !endblock
637    
638     C<next> gibt dabei ein Event-Objekt zurück, ähnlich dem Event-Objekt
639     das Callbacks des Event-Moduls erhalten. Eine frühe Implementation von
640     C<next> gab tatsächlich genau dieses Objekt zurück:
641    
642     !block "perl"
643     # dies ist der Callback, der jedem Event-Watcher zugewiesen wird:
644     sub std_cb {
645     # das private-Feld enthält ein Array,
646     # das im ersten Element den wartenden Prozess
647     # und im zweiten das Event-Objekt speichert
648     my $w = $_[0]->w;
649     my $q = $w->private;
650     $q->[1] = $_[0];
651     if ($q->[0]) { # somebody waiting?
652     $q->[0]->ready;
653     &Coro::schedule;
654     } else {
655     $w->stop;
656     }
657     }
658    
659     sub next {
660     my $w = $_[0];
661     my $q = $w->private;
662     if ($q->[1]) { # event waiting?
663     $w->again unless $w->is_cancelled;
664     } elsif ($q->[0]) {
665     croak "only one coroutine can wait for an event";
666     } else {
667     local $q->[0] = $Coro::current;
668     &Coro::schedule;
669     }
670     pop @$q;
671     }
672     !endblock
673    
674     Dies war nicht nur relativ ineffizient (zwei Prozesswechsel pro Ereignis),
675     das Event-Modul mochte das auch garnicht, da es die Event-Objekte intern
676     recycled und Zugriffe darauf nach Rückkehr aus dem Callback recht
677     zufällig bearbeitete.
678    
679     Die Lösung für beide Probleme ist wieder einmal XS. Zum Glück
680     exportiert C<Event> eine fast dokumentierte Schnittstelle dafür (wie auch
681     Coro eine XS-Schnittstelle bereitstellt). C<Coro::Event> speichert die
682     Event-Daten in einem Array, wobei nur die Werte für C<hits>, C<prio> und
683     C<got> gesichert werden, da kein Event mehr als diese benötigt.
684    
685     Durch Events kann es passieren, daß alle Prozesse auf ein Ereignis warten, also muss
686     der Idle-Prozess überschrieben werden:
687    
688     !block "perl"
689     $Coro::idle = new Coro sub {
690     while () {
691     Event::one_event; # inefficient
692     Coro::schedule;
693     }
694     };
695     !endblock
696    
697     C<one_event> ist nicht sehr effizient, weshalb man das Hauptprogramm am
698     besten durch einen Aufruf von C<Event::loop> zur Hauptschleife degradiert
699     und der Idle-Prozess nie laufen muss.
700    
701     Um nicht bei jedem Ereignis zwei Prozesswechsel durchführen zu müssen,
702     legt der Callback die wartenden Prozesse nur in die Ready-Queue. Dabei
703     ergibt sich das Problem, daß Event keine dokumentierte Möglichkeit
704     bietet, {{vor}} dem Aufruf von C<poll> oder C<select> (oder was auch
705     immer intern verwendet wird) einen Callback auszuführen, der die
706     bereitstehenden Prozesse ausführt.
707    
708     Zwar kann man mit:
709    
710     !block "perl"
711     Event->add_hooks(prepare => ..);
712     !endblock
713    
714     Einen Callback für diesen Fall einbauen, nur wird er zu spät aufgerufen,
715     es gehen also Ereignisse verloren. Ausserdem quittiert Event einige
716     Aufrufe innerhalb dieses Callbacks mit Segmentation Faults.
717    
718     Die Lösung liegt in einem speziellen Idle-Watcher mit der Priorität
719     C<PRIO_NORMAL>. Idle-Watcher mit dieser Priorität werden kurz vor dem
720     Aufruf von C<poll> aufgerufen, andere Prioritäten führen zu zu häufigen
721     oder gar keinen Aufrufen.
722    
723     Wenn ein Eriegnis auftritt, wird mit C<$watcher->now> dieser Watcher
724     "gestartet", der dann solange Prozesse scheduled bis keine mehr laufen:
725    
726     !block "perl"
727     #define NEED_SCHEDULE if (!do_schedule) \
728     { \
729     do_schedule = 1; \
730     GEventAPI->now ((pe_watcher *)scheduler); \
731     }
732    
733     scheduler_cb(pe_event *pe)
734     {
735     while (CORO_NREADY)
736     CORO_CEDE;
737    
738     do_schedule = 0;
739     }
740    
741     # overwrite the ready function
742     void
743     ready(self)
744     SV * self
745     PROTOTYPE: $
746     CODE:
747     NEED_SCHEDULE;
748     CORO_READY (self);
749     !endblock
750    
751     Wenn das Hauptprogramm artig C<Event::loop> benutzt, läuft dieser
752     Callback immer im Kontext des Hauptprogramms, der Idle-Prozess wird nicht
753     benutzt.
754    
755     H2: Non-Blocking but Blocking Filehandles
756    
757     Damit man das ganze sinnvoll (und natürlich) nutzen kann, braucht man
758     non-blocking-IO. Das Ziel ist es, Programme so schreiben zu können:
759    
760     !block "perl"
761     # Ein finger-Prozess, der andere Prozesse nicht blockiert
762     sub finger {
763     my $user = shift;
764     my $host = shift;
765    
766     my $fh = new Coro::Socket PeerHost => $host, PeerPort => "finger"
767     or die;
768    
769     print $fh "$user\n";
770    
771     print "$user\@$host: $_" while <$fh>;
772     print "$user\@$host: done\n";
773     }
774     !endblock
775    
776     Dazu muss man Filehandles tie'en, ein sehr komplizierter Prozess, da
777     Filehandles in Perl sehr merkwürdige Objekte, und vor allem keine Objekte
778     sind. Dies erledigt das C<Coro::Handle>-Modul, das im wesentlichen eine
779     Funktion C<unblock> exportiert, die aus einem normalen FileHandle einen
780     nichtblockierenden macht:
781    
782     !block "perl"
783     my $stdin = unblock \*STDIN;
784    
785     while(<$stdin>) {
786     ...
787     }
788     !endblock
789    
790     Anders als andere Module (C<Data::Location>) werden dabei keine
791     echten Filehandles erzeugt, da dies viel zu viel Probleme
792     mit sich bringt. Stattdessen wird ein anonymer GLOB an das
793     C<Coro::Handle::FH>-Package getied, um C<syswrite>, C<readline> etc.
794     abzufangen, zusätzlich wird der GLOB in das C<Coro::Handle>-Package
795     ge'bless'ed, um auch Methoden abzufangen:
796    
797     !block "perl"
798     my $fh = shift or return;
799     my $self = do { local *Coro::Handle };
800    
801     my ($package, $filename, $line) = caller;
802     $filename =~ s/^.*[\/\\]//;
803    
804     tie $self, Coro::Handle::FH, fh => $fh, desc => "$filename:$line", @_;
805    
806     my $_fh = select bless \$self, $class; $| = 1; select $_fh;
807     !endblock
808    
809     In C<Coro::Handle> stehen dann "glue"-Methoden:
810    
811 root 1.1 !block "perl"
812 root 1.2 sub readline { tied(${+shift})->READLINE(@_) }
813     sub read { Coro::Handle::FH::READ (tied ${$_[0]}, $_[1], $_[2], $_[3]) }
814     sub sysread { Coro::Handle::FH::READ (tied ${$_[0]}, $_[1], $_[2], $_[3]) }
815     sub syswrite { Coro::Handle::FH::WRITE (tied ${$_[0]}, $_[1], $_[2], $_[3]) }
816     sub print { Coro::Handle::FH::WRITE (tied ${+shift}, join "", @_) }
817     sub printf { Coro::Handle::FH::PRINTF(tied ${+shift}, @_) }
818     sub fileno { Coro::Handle::FH::FILENO(tied ${$_[0]}) }
819     sub close { Coro::Handle::FH::CLOSE (tied ${$_[0]}) }
820 root 1.1 !endblock
821    
822 root 1.2 Und einige weitere, die nur mit C<Coro::Handle>s Sinn machen:
823    
824 root 1.1 !block "perl"
825 root 1.2 sub readable { Coro::Handle::FH::readable(tied ${$_[0]}) }
826     sub writable { Coro::Handle::FH::writable(tied ${$_[0]}) }
827 root 1.1 !endblock
828    
829 root 1.2 Die eigentliche Implementation ist dann in C<Coro::Handle::FH> zu finden,
830     z.B. für C<WRITE>:
831    
832 root 1.1 !block "perl"
833 root 1.2 sub writable {
834     ($_[0][6] ||= Coro::Event->io(
835     fd => $_[0][0],
836     desc => "$_[0][1] W",
837     timeout => $_[0][2],
838     poll => W+E,
839     ))->next->{Coro::Event}[5] & W;
840     }
841    
842     sub WRITE {
843     my $len = defined $_[2] ? $_[2] : length $_[1];
844     my $ofs = $_[3];
845     my $res = 0;
846    
847     while() {
848     my $r = syswrite $_[0][0], $_[1], $len, $ofs;
849     if (defined $r) {
850     $len -= $r;
851     $ofs += $r;
852     $res += $r;
853     last unless $len;
854     } elsif ($! != Errno::EAGAIN) {
855     last;
856     }
857     last unless &writable;
858     }
859    
860     return $res;
861     }
862 root 1.1 !endblock
863    
864 root 1.2 Ja, die Hässlichkeit (C<READLINE> habe ich noch garnicht gezeigt ;) ist
865     ein Grund mehr, das ganze zu abstrahieren. Die eigentliche Arbeit wird von
866     der C<writable>-Methode erledigt, die beim ersten Aufruf einen Watcher
867     erzeugt und dann mit C<next> auf das nächste Ereignis wartet.
868    
869     Am Rande muss ich noch bemerken, dass "Ereignis" nicht ganz korrekt
870     ist. Weder C<select> noch C<poll> warten auf "Ereignisse", noch tun das
871     die meisten anderen Event-Modelle (manche jedoch tun das), sie prüfen
872     lediglich auf einen gewünschten Zustand, ist dieser shcon erreicht, wird
873     ein "Ereignis" ausgelöst, auch, wenn eigentlich nichts passiert ist.
874    
875     Und aus der Abteilung Kurioses: Wenn ein Filehandle in einen String
876     gewandelt wird, wird offenbar die C<FETCH>-Methode aufgerufen.
877    
878     H2: Von Handles zu Sockets
879    
880     Da Dateien niemals "blockieren" und Perl kein AIO unterstützt ist
881     C<Coro::Handle> eigentlich nur für Pipes und Sockets interessant. Damit
882     man auch ohne blockieren C<connect>en kann, gibt es mit C<Coro::Socket>
883     ein Modul, das sich so nah wie möglich an die C<IO::Socket::INET>-API
884     hält.
885    
886     Der Konstruktor benutzt die folgende Methode für ein
887     non-blocking-connect:
888    
889     !block "perl"
890     sub _prepare_socket {
891     my ($class, $arg) = @_;
892    
893     socket my $fh, PF_INET, $arg->{Type}, _proto($arg->{Proto})
894     or return;
895    
896     $fh = bless Coro::Handle->new_from_fh($fh, timeout => $arg{Timeout}), $class
897     or return;
898    
899     ...
900     }
901    
902     sub new {
903     ...
904     for (@sa) {
905     $fh = $class->_prepare_socket(\%arg)
906     or return;
907    
908     $! = 0;
909    
910     if ($fh->connect($_)) {
911     next unless writable $fh;
912     $! = unpack "i", $fh->getsockopt(SOL_SOCKET, SO_ERROR);
913     }
914    
915     $! or last;
916    
917     $!{ECONNREFUSED} or $!{ENETUNREACH} or $!{ETIMEDOUT} or $!{EHOSTUNREACH}
918     or return;
919     }
920     ...
921     }
922    
923     sub connect { connect tied(${$_[0]})->[0], $_[1] or $! == Errno::EINPROGRESS }
924     !endblock
925    
926     H1: Beispiele
927    
928     H2: Ein alter Traum: LWP non-blocking
929    
930     Wenn man auch Coro für sonst nichts braucht, auch in "normalen"
931     Programmen kann man Coro dazu benutzen, LWP (blockiert bei Anfragen) und
932     Ereignisgesteuerte Programme (z.B. Tk) zu kombinieren. Dazu muss man
933     "lediglich" den C<IO::Socket::INET>-Konstruktor überschreiben:
934    
935     !block "perl"
936     use Coro::Socket;
937     use IO::Socket::INET;
938     sub IO::Socket::INET::new {
939     shift; new Coro::Socket @_;
940     };
941     !endblock
942 root 1.1
943 root 1.2 Danach kann man loslegen und gleichzeitig mehrere LWP-Requests starten:
944    
945     !block "perl"
946     use Coro;
947     use Coro::Event;
948     use LWP::Simple;
949    
950     $SIG{PIPE} = 'IGNORE';
951    
952     async {
953     get "http://.../";
954    
955     };
956    
957     async {
958     get "http://.../";
959     };
960    
961     loop;
962     !endblock
963    
964     H2: Ein Prototyp für einen Server
965    
966     Ein "herkömmlicher" Server sieht im Pseudocode so aus:
967    
968     !block "perl"
969     my $socket = new Listen-Socket;
970    
971     while () {
972     my $fh = $socket->accpt;
973     if (fork == 0) {
974     serve_request;
975     exit;
976     }
977     }
978     !endblock
979    
980     Mit Coroutinen sieht das genauso aus, nur verwendet man statt C<fork> ein
981     C<async>:
982    
983     !block "perl"
984     sub handle_connection {
985     my $fh = $_[0];
986     while (<$fh>) {
987     ...
988     }
989     }
990    
991     my $port = new Coro::Socket
992     LocalPort => "imap2",
993     ReuseAddr => 1,
994     Listen => 1,
995     or die;
996    
997     async {
998     slog 1, "accepting connections";
999     while () {
1000     my $fh = $port->accept;
1001     slog 3, "accepted $fh on $port";
1002     async \&handle_connection, $fh;
1003     undef $fh;
1004     }
1005     };
1006    
1007     loop;
1008     !endblock
1009 root 1.1
1010 root 1.2 Die Vorteile sind - neben einem geringeren Verbrauch an Systemressourcen
1011     - das die einzelnen für die Clients zuständigen Prozesse untereinander
1012     kommunizieren können. Mein Webserver z.B. kann Informationen
1013     über Clients austauschen, mein IMAP-Server kann problemlos die
1014     asynchronen "neue Mail empfangen"-Nachrichten an angeschlossene Clients
1015     weitergeben. Man kann solche Serevr auch problemlos zusammen in denselben
1016     Prozess laden (dazu muss man nur eines der beiden C<loop>-Statements
1017     entfernen).
1018 root 1.1
1019 root 1.2 A1: Verfügbarkeit
1020 root 1.1
1021 root 1.2 Das Coro-Modul gibts auf CPAN - getestet wurde es bisher nur unter
1022     Linux/x86, IRIX und Cygwin, wobei es unter Cygwin wohl noch einige
1023     Probleme gibt, die ich aber nicht debuggen kann. Perl-5.6 ist
1024     Minimalversion, was daran liegt, daß ich Perl-5.6-Features für XS
1025     verwende. Ein Port auf ältere Perls sollte nicht schwer sein.
1026 root 1.1
1027 root 1.2 A2: Interessante URLs
1028 root 1.1
1029 root 1.2 Etwas Off-Topic, aber durchaus lesbar:
1030 root 1.1
1031 root 1.2 * Etwas Geschichte (Achtung, lustig!): http://brics.dk/~cw97/ProceedingS/01.ps.gz
1032     * Subcontinuations: http://indiana.edu/~dyb/papers/subK.ps
1033 root 1.1
1034    
1035    
1036    
1037