From 0ec3764d398add8c038b317201d139aaef4a594e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 23 Aug 2012 13:58:38 -0600 Subject: first draft of threads documentation --- doc/lispref/threads.texi | 238 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 doc/lispref/threads.texi (limited to 'doc/lispref/threads.texi') diff --git a/doc/lispref/threads.texi b/doc/lispref/threads.texi new file mode 100644 index 00000000000..760452808cf --- /dev/null +++ b/doc/lispref/threads.texi @@ -0,0 +1,238 @@ +@c -*-texinfo-*- +@c This is part of the GNU Emacs Lisp Reference Manual. +@c Copyright (C) 2012 +@c Free Software Foundation, Inc. +@c See the file elisp.texi for copying conditions. +@node Threads +@chapter Threads +@cindex threads +@cindex concurrency + + Emacs Lisp provides a limited form of concurrency, called +@dfn{threads}. All the threads in a given instance of Emacs share the +same memory. Concurrency in Emacs Lisp is ``mostly cooperative'', +meaning that Emacs will only switch execution between threads at +well-defined times. However, the Emacs thread support has been +designed in a way to later allow more fine-grained concurrency, and +correct programs should not rely on cooperative threading. + + Currently, thread switching will occur upon explicit request via +@code{thread-yield}, when waiting for keyboard input or for process +output (e.g., during @code{accept-process-output}), or during blocking +operations relating to threads, such as mutex locking or +@code{thread-join}. + + Emacs Lisp provides primitives to create and control threads, and +also to create and control mutexes and condition variables, useful for +thread synchronization. + + While global variables are shared among all Emacs Lisp threads, +local variables are not---a dynamic @code{let} binding is local. + + In the case of lexical bindings (@pxref{Variable Scoping}), a +closure is an object like any other in Emacs Lisp, and bindings in a +closure are shared by any threads invoking the closure. + +@menu +* Basic Thread Functions:: Basic thread functions. +* Mutexes:: Mutexes allow exclusive access to data. +* Condition Variables:: Inter-thread events. +@end menu + +@node Basic Thread Functions +@section Basic Thread Functions + + Threads can be created and waited for. A thread cannot be exited +directly, but the current thread can be exited implicitly, and other +threads can be signaled. + +@defun make-thread function &optional name +Create a new thread of execution which invokes @var{function}. When +@var{function} returns, the thread exits. + +@var{name} can be supplied to give a name to the thread. The name is +used for debugging and informational purposes only; it has no meaning +to Emacs. If @var{name} is provided, it must be a string. + +This function returns the new thread. +@end defun + +@defun threadp object +This function returns @code{t} if @var{object} represents an Emacs +thread, @code{nil} otherwise. +@end defun + +@defun thread-join thread +Block until @var{thread} exits, or until the current thread is signaled. +@end defun + +@defun thread-signal thread error-symbol data +Like @code{signal} (@pxref{Signaling Errors}), but the signal is +delivered in the thread @var{thread}. If @var{thread} is the current +thread, then this just calls @code{signal} immediately. +@code{thread-signal} will cause a thread to exit a call to +@code{mutex-lock}, @code{condition-wait}, or @code{thread-join}. +@end defun + +@defun thread-yield +Yield execution to the next runnable thread. +@end defun + +@defun thread-name thread +Return the name of @var{thread}, as specified to @code{make-thread}. +@end defun + +@defun thread-alive-p thread +Return @code{t} if @var{thread} is alive, or @code{nil} if it is not. +A thread is alive as long as its function is still executing. +@end defun + +@defun thread-blocker thread +Return the object that @var{thread} is waiting on. This function is +primarily intended for debugging. + +If @var{thread} is blocked in @code{thread-join}, this returns the +thread for which it is waiting. + +If @var{thread} is blocked in @code{mutex-lock}, this returns the mutex. + +If @var{thread} is blocked in @code{condition-wait}, this returns the +condition variable. + +Otherwise, this returns @code{nil}. +@end defun + +@defun current-thread +Return the current thread. +@end defun + +@defun all-threads +Return a list of all the live thread objects. A new list is returned +by each invocation. +@end defun + +@node Mutexes +@section Mutexes + + A @dfn{mutex} is an exclusive lock. At any moment, zero or one +threads may own a mutex. If a thread attempts to acquire a mutex, and +the mutex is already owned by some other thread, then the acquiring +thread will block until the mutex becomes available. + + Emacs Lisp mutexes are of a type called @dfn{recursive}, which means +that a thread can re-acquire a mutex it owns any number of times. A +mutex keeps a count of how many times it has been acquired, and each +acquisition of a mutex must be paired with a release. The last +release by a thread of a mutex reverts it to the unowned state, +potentially allowing another thread to acquire the mutex. + +@defun mutexp object +This function returns @code{t} if @var{object} represents an Emacs +mutex, @code{nil} otherwise. +@end defun + +@defun make-mutex &optional name +Create a new mutex and return it. If @var{name} is specified, it is a +name given to the mutex. It must be a string. The name is for +debugging purposes only; it has no meaning to Emacs. +@end defun + +@defun mutex-name mutex +Return the name of @var{mutex}, as specified to @code{make-mutex}. +@end defun + +@defun mutex-lock mutex +This will block until this thread acquires @var{mutex}, or until this +thread is signaled using @code{thread-signal}. If @var{mutex} is +already owned by this thread, this simply returns. +@end defun + +@defun mutex-unlock mutex +Release @var{mutex}. If @var{mutex} is not owned by this thread, this +will signal an error. +@end defun + +@defmac with-mutex mutex body@dots{} +This macro is the simplest and safest way to evaluate forms while +holding a mutex. It acquires @var{mutex}, invokes @var{body}, and +then releases @var{mutex}. It returns the result of @var{body}. +@end defmac + +@node Condition Variables +@section Condition Variables + + A @dfn{condition variable} is a way for a thread to block until some +event occurs. A thread can wait on a condition variable, to be woken +up when some other thread notifies the condition. + + A condition variable is associated with a mutex and, conceptually, +with some condition. For proper operation, the mutex must be +acquired, and then a waiting thread must loop, testing the condition +and waiting on the condition variable. For example: + +@example +(with-mutex mutex + (while (not global-variable) + (condition-wait cond-var))) +@end example + + The mutex ensures atomicity, and the loop is for robustness---there +may be spurious notifications. Emacs Lisp provides a macro, +@code{until-condition}, to do this automatically. + + Similarly, the mutex must be held before notifying the condition. +The typical, and best, approach is to acquire the mutex, make the +changes associated with this condition, and then signal it: + +@example +(with-mutex mutex + (setq global-variable (some-computation)) + (condition-signal cond-var)) +@end example + +@defun make-condition-variable mutex &optional name +Make a new condition variable associated with @var{mutex}. If +@var{name} is specified, it is a name given to the condition variable. +It must be a string. The name is for debugging purposes only; it has +no meaning to Emacs. +@end defun + +@defun condition-variable-p object +This function returns @code{t} if @var{object} represents a condition +variable, @code{nil} otherwise. +@end defun + +@defun condition-wait cond +Wait for another thread to notify @var{cond}, a condition variable. +This function will block until the condition is notified, or until a +signal is delivered to this thread using @code{thread-signal}. + +It is an error to call @code{condition-wait} without holding the +condition's associated mutex. + +@code{condition-wait} releases the associated mutex while waiting. +This allows other threads to acquire the mutex in order to notify the +condition. +@end defun + +@defun condition-notify cond &optional all +Notify @var{cond}. The mutex with @var{cond} must be held before +calling this. Ordinarily a single waiting thread is woken by +@code{condition-notify}; but if @var{all} is not @code{nil}, then all +threads waiting on @var{cond} are notified. + +@code{condition-notify} releases the associated mutex while waiting. +This allows other threads to acquire the mutex in order to wait on the +condition. +@c why bother? +@end defun + +@defun condition-name cond +Return the name of @var{cond}, as passed to +@code{make-condition-variable}. +@end defun + +@defun condition-mutex cond +Return the mutex associated with @var{cond}. Note that the associated +mutex cannot be changed. +@end defun -- cgit v1.2.1