mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Update "Asyncs" section of manual.
* doc/ref/api-scheduling.texi (Asyncs): Update.
This commit is contained in:
parent
728068113d
commit
51d322b2d4
1 changed files with 44 additions and 35 deletions
|
@ -8,7 +8,7 @@
|
|||
@section Threads, Mutexes, Asyncs and Dynamic Roots
|
||||
|
||||
@menu
|
||||
* Asyncs:: Asynchronous procedure invocation.
|
||||
* Asyncs:: Asynchronous interrupts.
|
||||
* Atomics:: Atomic references.
|
||||
* Threads:: Multiple threads of execution.
|
||||
* Mutexes and Condition Variables:: Synchronization primitives.
|
||||
|
@ -22,31 +22,48 @@
|
|||
|
||||
|
||||
@node Asyncs
|
||||
@subsection Asyncs
|
||||
@subsection Asynchronous Interrupts
|
||||
|
||||
@cindex asyncs
|
||||
@cindex asynchronous interrupts
|
||||
@cindex interrupts
|
||||
|
||||
Asyncs are a means of deferring the execution of Scheme code until it is
|
||||
safe to do so.
|
||||
Every Guile thread can be interrupted. Threads running Guile code will
|
||||
periodically check if there are pending interrupts and run them if
|
||||
necessary. To interrupt a thread, call @code{system-async-mark} on that
|
||||
thread.
|
||||
|
||||
Asyncs are integrated into the core of Guile. A running Guile program
|
||||
will periodically check if there are asyncs to run, invoking them as
|
||||
needed. For example, it is not possible to execute Scheme code in a
|
||||
POSIX signal handler, but in Guile a signal handler can enqueue a system
|
||||
async to be executed in the near future, when it is safe to do so.
|
||||
@deffn {Scheme Procedure} system-async-mark proc [thread]
|
||||
@deffnx {C Function} scm_system_async_mark (proc)
|
||||
@deffnx {C Function} scm_system_async_mark_for_thread (proc, thread)
|
||||
Enqueue @var{proc} (a procedure with zero arguments) for future
|
||||
execution in @var{thread}. When @var{proc} has already been enqueued
|
||||
for @var{thread} but has not been executed yet, this call has no effect.
|
||||
When @var{thread} is omitted, the thread that called
|
||||
@code{system-async-mark} is used.
|
||||
@end deffn
|
||||
|
||||
Asyncs can also be queued for threads other than the current one. This
|
||||
way, you can cause threads to asynchronously execute arbitrary code.
|
||||
Note that @code{scm_system_async_mark_for_thread} is not
|
||||
``async-signal-safe'' and so cannot be called from a C signal handler.
|
||||
(Indeed in general, @code{libguile} functions are not safe to call from
|
||||
C signal handlers.)
|
||||
|
||||
To cause the future asynchronous execution of a procedure in a given
|
||||
thread, use @code{system-async-mark}.
|
||||
Though an interrupt procedure can have any side effect permitted to
|
||||
Guile code, asynchronous interrupts are generally used either for
|
||||
profiling or for prematurely cancelling a computation. The former case
|
||||
is mostly transparent to the program being run, by design, but the
|
||||
latter case can introduce bugs. Like finalizers (@pxref{Foreign Object
|
||||
Memory Management}), asynchronous interrupts introduce concurrency in a
|
||||
program. An asyncronous interrupt can run in the middle of some
|
||||
mutex-protected operation, for example, and potentially corrupt the
|
||||
program's state.
|
||||
|
||||
Automatic invocation of asyncs can be temporarily disabled by calling
|
||||
@code{call-with-blocked-asyncs}. This function works by temporarily
|
||||
increasing the @emph{async blocking level} of the current thread while a
|
||||
given procedure is running. The blocking level starts out at zero, and
|
||||
whenever a safe point is reached, a blocking level greater than zero
|
||||
will prevent the execution of queued asyncs.
|
||||
If some bit of Guile code needs to temporarily inhibit interrupts, it
|
||||
can use @code{call-with-blocked-asyncs}. This function works by
|
||||
temporarily increasing the @emph{async blocking level} of the current
|
||||
thread while a given procedure is running. The blocking level starts
|
||||
out at zero, and whenever a safe point is reached, a blocking level
|
||||
greater than zero will prevent the execution of queued asyncs.
|
||||
|
||||
Analogously, the procedure @code{call-with-unblocked-asyncs} will
|
||||
temporarily decrease the blocking level of the current thread. You
|
||||
|
@ -59,22 +76,6 @@ In addition to the C versions of @code{call-with-blocked-asyncs} and
|
|||
inside a @dfn{dynamic context} (@pxref{Dynamic Wind}) to block or
|
||||
unblock asyncs temporarily.
|
||||
|
||||
@deffn {Scheme Procedure} system-async-mark proc [thread]
|
||||
@deffnx {C Function} scm_system_async_mark (proc)
|
||||
@deffnx {C Function} scm_system_async_mark_for_thread (proc, thread)
|
||||
Mark @var{proc} (a procedure with zero arguments) for future execution
|
||||
in @var{thread}. When @var{proc} has already been marked for
|
||||
@var{thread} but has not been executed yet, this call has no effect.
|
||||
When @var{thread} is omitted, the thread that called
|
||||
@code{system-async-mark} is used.
|
||||
|
||||
As we mentioned above, Scheme signal handlers are already called within
|
||||
an async and so can run any Scheme code. However, note that the C
|
||||
function is not safe to be called from C signal handlers. Use
|
||||
@code{scm_sigaction} or @code{scm_sigaction_for_thread} to install
|
||||
signal handlers.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} call-with-blocked-asyncs proc
|
||||
@deffnx {C Function} scm_call_with_blocked_asyncs (proc)
|
||||
Call @var{proc} and block the execution of asyncs by one level for the
|
||||
|
@ -113,6 +114,14 @@ one level. This function must be used inside a pair of calls to
|
|||
Wind}).
|
||||
@end deftypefn
|
||||
|
||||
Finally, note that threads can also be interrupted via POSIX signals.
|
||||
@xref{Signals}. As an implementation detail, signal handlers will
|
||||
effectively call @code{system-async-mark} in a signal-safe way,
|
||||
eventually running the signal handler using the same async mechanism.
|
||||
In this way you can temporarily inhibit signal handlers from running
|
||||
using the above interfaces.
|
||||
|
||||
|
||||
@node Atomics
|
||||
@subsection Atomics
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue