Next: iklib coroutines basic, Up: iklib coroutines [Index]
Coroutines are created by the function coroutine
; a coroutine in
execution can yield control to the next coroutine with the function
yield
. It is possible to enter a loop that runs all the
coroutines until all of them are finished with the function
finish-coroutines
.
All the examples in this section are to be considered as Scheme programs after the prelude:
#!r6rs (import (vicare)) (set-port-buffer-mode! (current-output-port) (buffer-mode line))
which allows the intertwining of coroutines to be seen by displaying strings on the current output port.
The following example runs two coroutines and waits for them to finish:
(coroutine (lambda () (display "one 1\n") (yield) (display "one 2\n") (yield) (display "one 3\n"))) (coroutine (lambda () (display "two 1\n") (yield) (display "two 2\n") (yield) (display "two 3\n"))) (finish-coroutines)
the output is:
one 1 two 1 one 2 two 2 one 3 two 3
We see that to exit a coroutine we just return from its start function.
We can always consider the ordinary control flow of a program as a coroutine, the main routine; so the following program produces output similar to the one above:
(coroutine (lambda () (display "sub 1\n") (yield) (display "sub 2\n") (yield) (display "sub 3\n"))) ;;This runs in the main routine. (display "main 1\n") (yield) (display "main 2\n") (yield) (display "main 3\n") (finish-coroutines)
the output is:
sub 1 main 1 sub 2 main 2 sub 3 main 3
It is perfectly all right to call yield
and
finish-coroutines
from the main routine even when there are no
subroutines:
(display "main 1\n") (yield) (display "main 2\n") (yield) (display "main 3\n") (finish-coroutines)
the output of this program is just:
main 1 main 2 main 3
It is possible to call finish-coroutines
from any coroutine, but
we must be careful because if we let the main routine exit before all
the routines are finished some computation will not take place. In the
following program the subroutine has more steps than the main routine:
(coroutine (lambda () (display "sub 1\n") (yield) (display "sub 2\n") (yield) (display "sub 3\n") (yield) (display "sub 4\n") (yield) (display "sub 5\n") (finish-coroutines))) ;; This runs in the main routine. (display "main 1\n") (yield) (display "main 2\n") (yield) (display "main 3\n")
and its output is:
sub 1 main 1 sub 2 main 2 sub 3 main 3
we see that ‘sub 4’ and ‘sub 5’ are not displayed.
It can be useful to register finish-coroutines
as exit hook, so
that upon exiting the process all the pending coroutines are correctly
terminated.
(coroutine (lambda () (display "one 1\n") (yield) (display "one 2\n") (yield) (display "one 3\n"))) (coroutine (lambda () (display "two 1\n") (yield) (display "two 2\n") (yield) (display "two 3\n"))) (exit-hooks (cons finish-coroutines (exit-hooks))) (exit)
Next: iklib coroutines basic, Up: iklib coroutines [Index]