![]() | ![]() | ![]() | Portable Threads | ![]() |
GBBopen's Portable Threads provides a uniform interface to commonly used
thread (multiprocessing) entities. Wherever possible, these entities
do something reasonable in Common Lisp implementations that do not provide
threads. However, entities that make no sense without threads signal errors in
non-threaded implementations (as noted with each entity). The feature
:threads-not-available:with-timeout-not-available
Portable Threads entities are provided by the :portable-threadsportable-threads.lisp
Common Lisp implementations that provide multiprocessing capabilities use one of two approaches:
There are advantages and complexities associated with each approach, and the Portable Threads Interface is designed to provide a uniform abstraction over them that can be used to code applications that perform consistently and efficiently on any supported Common Lisp implementation.
Common Lisp implementations provide differing semantics for the behavior of
mutual-exclusion locks that are acquired recursively by the same
thread: some always allow recursive use, others provide special
“recursive” lock objects in addition to non-recursive locks, and still
others allow recursive use to be specified at the time that a lock is being
acquired. To enable behavioral consistency in all Common Lisp
implementations, the :portable-threads
POSIX-style condition variables provide an atomic means for a thread to release a lock that it holds and go to sleep until it is awakened by another thread. Once awakened, the lock that it was holding is reacquired atomically before the thread is allowed to do anything else.
A condition variable must always be associated with a lock (or
recursive lock) in order to avoid a race condition created when one
thread signals a condition while another thread is preparing to wait on it.
In this situation, the second thread would be perpetually waiting for the
signal that has already been sent. In the POSIX model, there is no explicit
link between the lock used to control access to the condition variable and the
condition variable. The Portable Threads Interface makes this association
explicit by bundling the lock with the
Sometimes it is desirable to put a thread to sleep (perhaps for a long time) until some event has occurred. The Portable Threads Interface provides two entities that make this situation easy to code:
When a thread is hibernating, it remains available to respond to
Thread coordination functions, such as process-waitprocess-wait
Fortunately, most uses of process-waitprocess-waitprocess-wait
A scheduled function is an object that contains a function to be run at a specified time. When that specified time arrives, the function is invoked with a single argument: the scheduled function object. A repeat interval (in seconds) can also be specified for the scheduled function. This value is used whenever the scheduled function is invoked to schedule itself again at a new time relative to the current invocation. Scheduled functions can be scheduled to a resolution of one second.
Scheduled functions are scheduled and invoked by a separate
"Scheduled-Function Scheduler"
A periodic function is a function to be run repeatedly at a
specified interval. Unlike scheduled functions, which can be
scheduled only to a resolution of one second, a periodic function can
be repeated at intervals as brief as is supported by the sleep
Entities
The GBBopen Project
![]() | ![]() | ![]() | Portable Threads | ![]() |