ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/docs/pws2002/coro.sdf
Revision: 1.5
Committed: Sun Feb 10 16:39:35 2002 UTC (24 years, 7 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +1 -1 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 root 1.3 Prozedurale Programme laufen normalerweise sequenziell ab und springen
10 root 1.2 manchml in Unterprogramme/Funktionen. Es ist nicht möglich, aus einem
11     Unterprogramm heraus kurzzeitig in den Aufrufer zurückzuspringen und später
12 root 1.3 an derselben Stelle weiterzuarbeiten.
13 root 1.2
14 root 1.3 Dies liegt daran, dass Perl, wie viele andere Sprachen, Funktionsaufrufe
15 root 1.2 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 root 1.3 Aufruffolge, sondern viele. Zwischen diesen kann an beliebigen Stellen
20 root 1.2 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 root 1.3 dass der Eindruck gleichzeitigen Ablaufs entstehen kann (kooperatives
26     Multitasking). Der Unterschied zu Continuations ist im Wesentlichen der,
27     dass der Wechsel normalerweise nicht explizit erfolgt und keine Parameter
28 root 1.2 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 root 1.3 aber da ich immer dachte, man könne das nicht schnell genug (Kopieren des
35     gesamten Stacks oder schlimmer?) implementieren bzw. die Implementation
36     wäre viel zu komplex um jemals stabil zu laufen.
37 root 1.1
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 root 1.3 C<NEWPROCESS> erzeugt einen neuen "Prozess", wobei ein "Prozess" im
47     Wesentlichen einen Aufrufstack (zum Schachteln von Funktionsaufrufen)
48 root 1.1 und einen Startpunkt (C<coderef>) besitzt. Diese Daten werden in einer
49     Struktur (C<process>) abgelegt.
50    
51 root 1.3 Um einen solchen Prozess zu starten muss 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.3 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 root 1.3 Damit lassen sich Continuations und kooperatives und präemptives
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 root 1.3 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.3 (Es folgen einige haarsträubende Implementationsdetails, wer will, kann
70 root 1.2 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 root 1.3 das die beiden obigen Primitiven implementiert. Es funktionierte sogar:
74 root 1.1
75 root 1.4 !block C
76 root 1.1 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 root 1.3 diese (genauer: den CV) selbst:
106 root 1.1
107 root 1.4 !block C
108 root 1.1 /* 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 root 1.4 in die Quere kommen. C<pp_entersub> ist alles andere als trivial, ein
126 root 1.3 Wunder, dass Perl so schnell ist.
127 root 1.1
128 root 1.3 Im Wesentlichen geht es darum, für jede Rekursionsstufe eine C<padlist>
129     (in der werden lokale Variablen u.ä. gespeichert) zu erzeugen, die erste
130     schon beim Kompilieren.
131 root 1.1
132     Solange eine Coroutine nicht in eine Funktion springt, die schon rekursiv
133 root 1.3 aufgerufen wurde, ist das kein Problem, da C<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.3 zurückkehren will, gibt es ein Problem, denn das käme der Aufgabe
137     gleich, die n-te Rekursionsstufe zu beenden während die n+1-te noch 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.3 Perl-Thread-Implementation kann sich das leisten), muss man den Aufrufstack
143     hinaufgewandern und manuell eine Art "Rücksprung" organisieren.
144 root 1.1
145 root 1.4 !block C
146 root 1.1 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.3 Denn, während man die neu erzeugten padlists einfach sichern kann, muss
207     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.3 Damit war bewiesen, dass Coroutinen tatsächlich so viele Probleme machen,
211 root 1.2 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.3 diese wieder einen Perl-Callback. Der führt einen Coroutinenwechsel
217 root 1.1 durch und die neue Coroutinen macht ein C<return> - wohin? In die
218 root 1.3 XS-Funktion, die natürlich Ergebnisse auf dem Stack erwartet, die ebenso
219     natürlich nicht da sind. dies ist auch der Grund dafür, dass der "fake
220 root 1.2 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.3 kein System bekannt, dass sich wirklich ganz an den Standard hielte
229     (von Grausamkeiten wie IRIX mal ganz abgesehen, siehe sigaltstack,
230     das vollkommen dokumentiert das vollkommen sinnlose macht), aber die
231     Unterschiede sind gering. Sogar unter der eingeschränkten Win32-API kann
232     man durch direktes herumpoken in C<jmp_buf> relativ schmerzlos eine
233 root 1.1 Implementation bekommen.
234    
235     Im Coro-Modul gibt es im Verzeichnis C<Coro/libcoro> seitdem eine
236     relativ portable, sehr kleine (366 Zeilen inkl. Dokumentation ;)
237 root 1.2 Coroutinenimplementation für C.
238 root 1.1
239 root 1.2 Das Coro-Modul erzeugt entweder für jede Coroutine in Perl eine Coroutine
240 root 1.1 in C, oder optional nur "on demand", d.h. wenn sich der C-Stackpointer
241 root 1.2 verändert hat, eine gefährliche, aber in der Praxis gut funktionierende
242 root 1.1 Heuristik.
243    
244     H1: Teil 2: Implementation von Coroutinen und Continuations in Perl
245    
246     H2: Die Perl-API
247    
248     C<NEWPROCESS> und C<TRANSFER> werden vom C<Coro::State>-Modul implementiert.
249     C<NEWPROCESS> sieht in Perl so aus:
250    
251 root 1.4 !block perl
252 root 1.2 # eine "leere" Coroutine, bereit, gefüllt zu werden
253 root 1.1 $main = new Coro::State;
254    
255     # eine neue Coroutine, zu der man wechseln kann
256     $new = new Coro::State sub {
257     # ... coroutine
258     }, @args;
259     !endblock
260    
261     Und C<TRANSFER> sieht so aus:
262    
263 root 1.4 !block perl
264 root 1.1 # etwas asymetrisch:
265     $main->transfer($new);
266     # oder symmetrischer
267     Coro::State::transfer($main,$new);
268     !endblock
269    
270     H2: Continuations
271    
272 root 1.3 Nicht, dass ich das Modul viel benutzen würde, aber ich wollte zeigen,
273     dass es geht: Das C<Coro::Cont>-Modul exportiert zwei Funktionen, C<csub>,
274 root 1.1 mit dem sich neue Continuations erzeugen lassen und C<yield>, das so
275 root 1.3 ähnlich wie C<return> wirkt. Außerdem werden Attribute unterstützt, so,
276     dass man Continuations so schreiben kann:
277 root 1.1
278 root 1.4 !block perl
279 root 1.1 use Coro::Cont;
280    
281     sub generator : Cont {
282     my $state = time;
283     while() {
284     $state = $state * 31231 % 65531;
285     yield $state % $_[0];
286     }
287     }
288     !endblock
289    
290 root 1.3 Der erste Aufruf initialisiert den Zustand (Zuweisung an C<$state>), bei
291     jedem weiteren wird eine (schlechte) Zufallszahl im Bereich C<0..$_[0]>
292 root 1.2 zurückgeliefert, wobei @_ sich jedesmal ändert. Das Attributsystem von
293 root 1.3 Perl5 ist ziemlich schwer zu benutzen (mehrere Module können es sich nicht
294     einfach teilen, Attribute sind automatisch global etc..), weshalb ich
295     darauf nicht näher eingehe ;)
296 root 1.1
297 root 1.3 Die Implementation ist einigermaßen trickreich, da die Standardimplementation
298 root 1.2 von C<transfer> das Array C<@_> mitspeichert, es also nicht so einfach übergeben
299 root 1.1 werden kann. Deshalb kann man C<transfer> ein drittes Argument, eine Bitmaske
300 root 1.2 mit Flags, übergeben, die angibt, ob C<@_> oder C<$_> u.ä. Teil des
301 root 1.1 "Prozesszustandes" werden oder nicht.
302    
303 root 1.2 C<csub> erzeugt zwei C<Coro::State>-Objekte, eines für den Aufrufer und eines
304     für die Continuation:
305 root 1.1
306 root 1.4 !block perl
307 root 1.1 sub csub(&) {
308     my $code = $_[0];
309     my $prev = new Coro::State;
310    
311     my $coro = new Coro::State sub {
312     # we do this superfluous switch just to
313     # avoid the parameter passing problem
314     # on the first call
315     &yield;
316     &$code while 1;
317     };
318     !endblock
319    
320 root 1.3 D.h. die Code-Referenz wird in einer Schleife aufgerufen. Da die Parameter
321 root 1.2 beim ersten Aufruf der Coroutine etwas anders übergeben werden als
322 root 1.3 später bei C<yield>, wird als erstes ein C<yield> ausgeführt, damit alle
323 root 1.1 Aufrufe identisch sind.
324    
325 root 1.2 Als nächstes wird die neu erzeugte Coroutine {{einmal}} aufgerufen (damit
326 root 1.1 sie "yield"-en kann):
327    
328 root 1.4 !block perl
329 root 1.1 push @$$return, [$coro, $prev];
330     &Coro::State::transfer($prev, $coro, 0);
331     !endblock
332    
333 root 1.3 In der gobalen Variablen C<$return> befindet sich eine Referenz
334     auf ein Array, in dem die "Rücksprung"-Coroutinen gespeichert sind,
335 root 1.1 d.h. C<Coro::Cont> macht fast den gleichen "Fehler" wie C<pp_entersub>,
336     aber C<$$return> ist nicht wirklich global (wie ich gleich zeige ;)
337    
338 root 1.3 Als letztes wird eine Code-Referenz zurückgegeben, die das Aufrufen der
339 root 1.2 Coroutine für uns erledigt:
340 root 1.1
341 root 1.4 !block perl
342 root 1.1 return sub {
343     push @$$return, [$coro, $prev];
344     &Coro::State::transfer($prev, $coro, 0);
345     wantarray ? @_ : $_[0];
346     };
347     !endblock
348    
349 root 1.2 Auch hier wird die "Rücksprungaddresse" für C<yield> in C<@$$return>
350     gespeichert und dann die Coroutine aufgerufen, die beim nächsten C<yield>
351     zurückkehrt. Die Argumente, die die Coroutine an C<yield> übergeben hat,
352 root 1.1 stehen immer noch in C<@_>.
353    
354     Die Funktion C<yield> ist in XS implementiert, die
355     Prototyp-Implementation in Perl sah jedoch so aus:
356    
357 root 1.4 !block perl
358 root 1.1 sub yield(@) {
359     &Coro::State::transfer(@{pop @$$return}, 0);
360     wantarray ? @_ : $_[0];
361     }
362     !endblock
363    
364 root 1.3 Auch nichts Überraschendes, es wird zum Aufrufer zurückgegeben. Beim
365 root 1.2 nächsten Aufruf wird das neue C<@_> zurückgegeben, d.h. der Aufruf
366     müsste lauten: C<@_ = yield ...>, und das ist der Grund, weshalb es
367 root 1.1 in XS implementiert wurde, denn in XS kann man das C<@_> des Aufrufers
368 root 1.2 verändern. Wäre nicht dieser Umstand. so würde auch C<yield> in reinem
369 root 1.1 Perl implementiert sein.
370    
371 root 1.2 Das verbleibende Problem ist die globale Variable C<$return>. Tatsächlich
372 root 1.1 ist sie ein C<Coro::Specific>-Objekt und ist "Coroutinen"spezifisch, d.h.
373     kann in jeder Coroutine (hier meine ich ein C<Coro>-Objekt und nicht das
374     C<Coro::State>-Objekt) einen anderen Wert besitzen.
375    
376     H2: C<Coro::Specific>
377    
378     Mit C<Coro::State> kann man eigene Prozess-Abstraktionen basteln. Damit
379 root 1.3 C<Coro::Specific> funktioniert, muss man lediglich einen
380 root 1.1 coroutinen-/prozessspezifischen Hash in C<$Coro::current> speichern, und
381     genau das macht das C<Coro>-Modul.
382    
383 root 1.2 C<Coro::Specific->new> gibt eine Referenz auf einen ge'tie'ten Scalar zurück, der
384 root 1.1 wiederum bei C<FETCH> und C<STORE> einen Skalar im Array
385 root 1.2 C<@{$Coro::current->{specific}}> verändert. Solange das C<Coro>-Modul nicht
386 root 1.3 geladen ist, ist das immer derselbe, danach ist er coroutinenspezifisch.
387 root 1.1
388 root 1.4 !block perl
389 root 1.1 my $idx;
390    
391     sub new {
392     my $var;
393     tie $var, Coro::Specific::;
394     \$var;
395     }
396    
397     sub TIESCALAR {
398     my $idx = $idx++;
399     bless \$idx, $_[0];
400     }
401    
402     sub FETCH {
403     $Coro::current->{specific}[${$_[0]}];
404     }
405    
406     sub STORE {
407     $Coro::current->{specific}[${$_[0]}] = $_[1];
408     }
409     !endblock
410    
411     Auf diese Weise kann man in anderen Modulen ohne schlechtes Gewissen
412     C<Coro::Specific> verwenden, da weder C<Coro::State> noch C<Coro> geladen
413 root 1.2 sein müssen.
414 root 1.1
415     H2: Prozesse selbst gemacht
416    
417 root 1.2 Der nächste Schritt, nach Continuations, Variablen und (primitiven)
418 root 1.1 Coroutinen sind richtige Prozesse. Diese werden im C<Coro>-Modul
419 root 1.3 implementiert, das Prozesserzeugung, Kommunikation, Prioritäten etc.
420 root 1.1 anbietet.
421    
422     Das sieht dann so aus:
423    
424 root 1.4 !block perl
425 root 1.1 use Coro:
426    
427     async {
428     # ein neuer "Prozess"
429     };
430    
431     my $coro = async {
432     terminate;
433     };
434    
435     $coro->prio(PRIO_MAX);
436 root 1.5 $coro->join;
437 root 1.1
438 root 1.2 cede; # gib die CPU frei für andere Prozesse
439 root 1.1
440     # usw.. hat ja "jeder" schon mal gesehen ;-]
441     !endblock
442    
443     Die Implementation ist in einigen Teilen in XS, der Geschwindigkeit
444     wegen. Wenn das Modul geladen wird, erzeugt es zuerst einen
445 root 1.2 "Hauptprozess", der für das Hauptprogramm steht (das Hauptprogramm
446 root 1.3 korrekt auf eine Coroutine abzubilden, ist sowieso ein sehr schwieriges
447 root 1.1 Unterfangen - welche Coroutine DESTROY't die anderen Coroutinen am
448 root 1.2 Programmende, wenn das Hauptprogramm nicht mehr existiert?) und sorgt für
449     die Übernahme des bisherigen C<@{$Coro::current->{specific}}>.
450 root 1.1
451 root 1.4 !block perl
452 root 1.1 our $main = new Coro;
453    
454     # maybe some other module used Coro::Specific before...
455     if ($current) {
456     $main->{specific} = $current->{specific};
457     }
458    
459     our $current = $main;
460     !endblock
461    
462 root 1.3 Dann folgt die Erzeugung eines Idle-Prozesses, der Rechenzeit verbrät,
463     wenn kein Prozess mehr läuft:
464 root 1.1
465 root 1.4 !block perl
466 root 1.1 our $idle = new Coro sub {
467     print STDERR "FATAL: deadlock detected\n";
468     exit(51);
469     };
470     !endblock
471    
472 root 1.3 Jaja, reingefallen. Wenn kein Prozess mehr läuft, haben wir einen
473     Deadlock, zumindest, solange man Signale außer acht lässt. Das ändert
474 root 1.1 sich, wenn man Events benutzt (z.B. mit C<Coro::Event>), weshalb der
475     Idle-Prozess auswechselbar ist.
476    
477     Neue Prozesse werden mit C<async> oder C<Coro->new> erzeugt:
478    
479 root 1.4 !block perl
480 root 1.1 sub _newcoro {
481     terminate &{+shift};
482     }
483    
484     sub new {
485     my $class = shift;
486     bless {
487     _coro_state => (new Coro::State $_[0] && \&_newcoro, @_),
488     }, $class;
489     }
490    
491     sub async(&@) {
492     my $pid = new Coro @_;
493     $manager->ready; # this ensures that the stack is cloned from the manager
494     $pid->ready;
495     $pid;
496     }
497     !endblock
498    
499 root 1.3 Ein Prozess ist also wenig mehr als ein nackter Hash, in dessen
500 root 1.2 C<_coro_state>-Slot ein C<Coro::State>-Objekt gespeichert ist. Ähnlich
501 root 1.1 wie PDL sieht C<transfer> in diesem Slot nach einem C<Coro::State>-Objekt.
502    
503 root 1.3 Dass C<async> den C<$manager> in Bereitschaft versetzt und nicht nur den
504     neuen Prozess, ist nicht auf Anhieb verständlich: Der Grund dafür ist,
505     dass so die meisten Prozesse mit einem definierten Stackpointer erzeugt
506     werden, so dass derselbe C-Stack für alle Prozesse verwendet werden kann,
507     zumindest anfänglich.
508 root 1.1
509     Am Ende eines Prozesslebens steht ein C<terminate>, oder ein C<cancel>:
510    
511 root 1.4 !block perl
512 root 1.1 sub cancel {
513     push @destroy, $_[0];
514     $manager->ready;
515     &schedule if $current == $_[0];
516     }
517     !endblock
518    
519 root 1.2 C<schedule> springt direkt in den Scheduler, der den nächsten
520     lauffähigen Prozess aus der Warteschlange nimmt und zum aktuellen
521 root 1.1 macht. Er ist (jaja, "the need for speed") in XS implementiert, sieht aber
522 root 1.3 etwa (keine Prioritäten) so aus:
523 root 1.1
524 root 1.4 !block perl
525 root 1.1 sub schedule {
526     my $previous = $current;
527     $current = shift @runqueue;
528     Coro::State::transfer($current, $previous);
529     }
530     !endblock
531    
532 root 1.3 Der aktuelle Prozess wird nicht automatisch wieder aufgerufen, dazu muss
533 root 1.1 man ihn wieder mit der C<ready>-Methode in die Warteschlange setzen. Um
534 root 1.3 nur kurz andere Prozesse laufen zu lassen, konnte man früher C<yield>
535 root 1.2 benutzen, aber das ging schon für Continuations drauf, und Damian Conway
536 root 1.3 fand das wichtiger. Also musste ich einen neuen Namen finden:
537 root 1.1
538 root 1.4 !block perl
539 root 1.1 sub cede {
540     $current->ready;
541     schedule;
542     }
543     !endblock
544    
545 root 1.2 Einen Prozess direkt zu zerstören, ist keine gute Idee. Zum einen könnte
546 root 1.3 er mehrfach in der C<ready>-Queue stehen, zum anderen sollte er sich
547     selbst C<DESTROY>en können, aber da er sich dabei selbst den C-Stack
548 root 1.1 wegzieht, muss dies von einem anderen Prozess aus stattfinden. Der
549 root 1.3 Manager-Prozess stellt genau dies sicher (und verständigt auch gleich
550 root 1.1 eventuell wartende Prozesse):
551    
552 root 1.4 !block perl
553 root 1.1 my @destroy;
554     my $manager;
555     $manager = new Coro sub {
556     while() {
557     # by overwriting the state object with the manager we destroy it
558     # while still being able to schedule this coroutine (in case it has
559     # been readied multiple times. this is harmless since the manager
560     # can be called as many times as neccessary and will always
561     # remove itself from the runqueue
562     while (@destroy) {
563     my $coro = pop @destroy;
564     $coro->{status} ||= [];
565     $_->ready for @{delete $coro->{join} || []};
566     $coro->{_coro_state} = $manager->{_coro_state};
567     }
568     &schedule;
569     }
570     };
571     !endblock
572    
573     H2: Signale, Semaphoren, Channels und Locks
574    
575     Hat man Prozesse, die man erzeugen, anhalten, schedulen und wieder beenden
576     kann, so muss man sie koordinieren. Zum Beispiel mit C<Coro::Signal>'s:
577    
578 root 1.4 !block perl
579 root 1.1 sub send {
580     if (@{$_[0][1]}) {
581     (shift @{$_[0][1]})->ready;
582     } else {
583     $_[0][0] = 1;
584     }
585     }
586    
587     sub wait {
588     if ($_[0][0]) {
589     $_[0][0] = 0;
590     } else {
591     push @{$_[0][1]}, $Coro::current;
592     Coro::schedule;
593     }
594     }
595     !endblock
596    
597 root 1.2 Getreu dem Motto "Pseudo-Hashes müssen sterben!", etwas ungewöhnlich
598 root 1.1 ausgelegt, verwendet C<Coro::Signal> ein Array und keinen Hash. Das erste
599 root 1.3 Element ist nur ein Flag, das angibt, ob das Signal gesendet wurde (falls
600     niemand darauf wartet). Das zweite Element ist ein Array wartender
601 root 1.1 Prozessen.
602    
603     C<send> weckt den ersten wartenden Prozess auf oder - falls es keinen gibt
604 root 1.2 - setzt das Flag. Wenn man auf ein Signal wartet, wird zuerst geprüft, ob
605 root 1.3 es schon aufgetreten ist, sonst reiht sich der aktuelle Prozess in die
606 root 1.1 Warteschlange und legt sich schlafen.
607    
608 root 1.3 H1: Teil 3: Die Außenwelt
609 root 1.1
610 root 1.2 H2: C<Event> für Coro: C<Coro::Event>
611    
612     Multitasking innerhalb von Perl ist ja ganz nett, aber das erste
613    
614 root 1.4 !block perl
615 root 1.2 my $line = <STDIN>;
616     !endblock
617    
618     bringt das ganze System zum Erliegen. Wenn man viele asynchrone
619 root 1.3 Ein-/Ausgabekanäle hat, die in unterschiedlicher Reihenfolge bedient
620 root 1.2 werden sollen, braucht man eine Ereignissteuerung. Das Standardmodul für
621 root 1.3 diesen Fall ist das (leider nicht mehr gewartete und auf vielen Systemen
622     nicht mehr lauffähige) Event-Modul, das jedoch für jedes Ereigenis einen
623     Callback erfordert.
624 root 1.2
625     Das C<Coro::Event>-Modul benutzt Event (oder ein anderes Modul, es gibt
626 root 1.3 nur keines ;), statt eines Callbacks wird der Prozess solange blockiert,
627 root 1.2 bis das Ereignis eintritt:
628    
629 root 1.4 !block perl
630 root 1.2 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 root 1.3 C<next> gibt dabei ein Event-Objekt zurück, ähnlich dem Event-Objekt,
639 root 1.2 das Callbacks des Event-Moduls erhalten. Eine frühe Implementation von
640     C<next> gab tatsächlich genau dieses Objekt zurück:
641    
642 root 1.4 !block perl
643 root 1.2 # 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 root 1.3 das Event-Modul mochte das auch gar nicht, da es die Event-Objekte intern
676     wiederverwendet und Zugriffe darauf nach Rückkehr aus dem Callback recht
677 root 1.2 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 root 1.3 Durch Events kann es passieren, dass alle Prozesse auf ein Ereignis warten, also muss
686 root 1.2 der Idle-Prozess überschrieben werden:
687    
688 root 1.4 !block perl
689 root 1.2 $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 root 1.3 ergibt sich das Problem, dass Event keine dokumentierte Möglichkeit
704 root 1.2 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 root 1.4 !block perl
711 root 1.2 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 root 1.3 Wenn ein Ereignis auftritt, wird mit C<$watcher->now> dieser Watcher
724 root 1.2 "gestartet", der dann solange Prozesse scheduled bis keine mehr laufen:
725    
726 root 1.4 !block perl
727 root 1.2 #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 root 1.3 Damit man das Ganze sinnvoll (und natürlich) nutzen kann, braucht man
758 root 1.2 non-blocking-IO. Das Ziel ist es, Programme so schreiben zu können:
759    
760 root 1.4 !block perl
761 root 1.2 # 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 root 1.3 Dazu muss man Filehandles tie'en, ein komplizierter Prozess, da
777 root 1.2 Filehandles in Perl sehr merkwürdige Objekte, und vor allem keine Objekte
778 root 1.3 sind. Dies erledigt das C<Coro::Handle>-Modul, das im Wesentlichen eine
779     Funktion C<unblock> exportiert, die aus einem normalen Filehandle einen
780 root 1.2 nichtblockierenden macht:
781    
782 root 1.4 !block perl
783 root 1.2 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 root 1.3 echten Filehandles erzeugt, da dies zu viele Probleme
792 root 1.2 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 root 1.4 !block perl
798 root 1.2 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.4 !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.4 !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.4 !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.3 Ja, die Hässlichkeit (C<READLINE> habe ich noch gar nicht gezeigt ;) ist
865     ein Grund mehr, das Ganze zu abstrahieren. Die eigentliche Arbeit wird von
866 root 1.2 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 root 1.3 ist. Weder C<select> noch C<poll> warten auf "Ereignisse", noch tun
871     das die meisten anderen Event-Modelle, sie prüfen lediglich auf einen
872     gewünschten Zustand, ist dieser schon erreicht, wird ein "Ereignis"
873     ausgelöst, auch, wenn eigentlich nichts passiert ist.
874 root 1.2
875 root 1.3 Und aus der Abteilung Kurioses: Beim Wandeln eines Filehandle in einen
876     String wird offenbar die C<FETCH>-Methode aufgerufen.
877 root 1.2
878     H2: Von Handles zu Sockets
879    
880 root 1.3 Da Dateien niemals "blockieren" und Perl kein AIO unterstützt, ist
881 root 1.2 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 root 1.4 !block perl
890 root 1.2 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 root 1.3 Wenn man Coro für sonst nichts braucht, auch in "normalen"
931 root 1.2 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 root 1.4 !block perl
936 root 1.2 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 root 1.4 !block perl
946 root 1.2 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 root 1.4 !block perl
969 root 1.3 my $socket = <neue listen-Socket erzeugen>
970 root 1.2
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 root 1.4 !block perl
984 root 1.2 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 root 1.3 - dass die einzelnen für die Clients zuständigen Prozesse untereinander
1012     kommunizieren können. Mein Webserver z.B. kann Informationen über Clients
1013     austauschen, mein IMAP-Server kann problemlos die asynchronen "neue Mail
1014     empfangen"-Nachrichten an angeschlossene Clients weitergeben. Man kann
1015     solche Server auch problemlos zusammen in denselben Prozess laden (dazu
1016     muss man nur eines der beiden C<loop>-Statements entfernen).
1017 root 1.1
1018 root 1.2 A1: Verfügbarkeit
1019 root 1.1
1020 root 1.2 Das Coro-Modul gibts auf CPAN - getestet wurde es bisher nur unter
1021     Linux/x86, IRIX und Cygwin, wobei es unter Cygwin wohl noch einige
1022     Probleme gibt, die ich aber nicht debuggen kann. Perl-5.6 ist
1023 root 1.3 Minimalversion, was daran liegt, dass ich Perl-5.6-Features für XS
1024     verwende. Ein Port auf ältere Perls sollte nicht schwierig sein.
1025 root 1.1
1026 root 1.2 A2: Interessante URLs
1027 root 1.1
1028 root 1.2 Etwas Off-Topic, aber durchaus lesbar:
1029 root 1.1
1030 root 1.2 * Etwas Geschichte (Achtung, lustig!): http://brics.dk/~cw97/ProceedingS/01.ps.gz
1031     * Subcontinuations: http://indiana.edu/~dyb/papers/subK.ps
1032 root 1.1
1033    
1034    
1035    
1036