Access to all Common Lisp objects is thread-safe in the sense that it does not cause an error because of threading issues.
This section outlines for which types of mutable Common Lisp object access is atomic. That is, each value read from the object will correspond to the state at some point in time. Note however, that if several values are read, there is no guarantee about how these values will relate to each other if they are being modified by another thread (see Issues with order of memory accesses).
When one of these mutable atomic objects is modified, readers see either the old or new value (not something else), and it is guaranteed that the Lisp image is not corrupted by the modification even if multiple threads read or write the object simultaneously.
The Common Lisp functions that access hash tables are atomic with respect to each other. See also modify-hash for atomic reading and writing an entry and with-hash-table-locked. See also Modifying a hash table with multiprocessing for thread-safe ways to ensure a table entry.
Access to synchronization objects (mailboxes, barriers, semaphores and condition variables) is atomic. More information about these objects is in Synchronization between threads.
Operations on editor buffers (including points) are atomic and thread-safe as long as their arguments are valid. This includes modification to the text. However, buffers and points may become invalid because of execution on another thread. The macros
editor:with-point-locked should be used around editor operations on buffers and points that may be affected by other processes. Note that this is applicable also to operations that do not actually modify the text, because they can behave inconsistently if the buffer they are looking at changes during the operation. See the
LispWorks Editor User Guide
for details of these macros.
Access to lists (including alists and plists) is not atomic. Lists are made of multiple cons objects, so although access to the individual conses is atomic, the same does not hold for the list as a whole.
Macros that expand to multiple accesses are in general not atomic. In particular, modifying macros like
incf are not atomic (but see the atomic versions of some of them in Low level atomic operations).
Making several calls to Common Lisp functions that access hash tables will not be atomic overall. However LispWorks provides thread-safe ways to ensure a hash table entry - see Modifying a hash table with multiprocessing. See also modify-hash for atomic reading and writing an entry and with-hash-table-locked.
Operations on CAPI objects are not atomic in general. The same is true for anything in the LispWorks IDE. These operations need to be invoked from the thread that owns the object, for example by
When multiple threads access the same memory location, the order of those accesses is not generally guaranteed. You should therefore not attempt to implement "lockless algorithms" which depend on the order of memory accesses unless you have a good understanding of multiprocessing issues at the CPU level (see Ensuring order of memory between operations in different threads).
However, all of the Low level atomic operations and locking operations (see Locks) do ensure that all memory accesses that happen before them have finished and that all memory accesses that happen after them start after them. Therefore, normally there is nothing special to consider when using those operations. The modification check macros described in Aids for implementing modification checks also take care of this.
make-hash-table argument single-thread tells
make-hash-table that the table is going to be used only in single thread context, and therefore does not need to be thread-safe. Such a table allows faster access.
make-array argument single-thread creates an array that is single threaded. Currently, the main effect of single-thread is on the speed of
vector-push-extend on non-simple vectors. These operations are much faster on "single threaded" vectors, typically more than twice as fast as "multithreaded" vectors.
You can also make an array be "single-threaded" with set-array-single-thread-p.
LispWorks User Guide and Reference Manual - 13 Feb 2015