Next: , Previous: Special Variables, Up: Threading


12.3 Mutex Support

Mutexes are used for controlling access to a shared resource. One thread is allowed to hold the mutex, others which attempt to take it will be made to wait until it's free. Threads are woken in the order that they go to sleep.

There isn't a timeout on mutex acquisition, but the usual WITH-TIMEOUT macro (which throws a TIMEOUT condition after n seconds) can be used if you want a bounded wait.

     (defpackage :demo (:use "CL" "SB-THREAD" "SB-EXT"))
     
     (in-package :demo)
     
     (defvar *a-mutex* (make-mutex :name "my lock"))
     
     (defun thread-fn ()
       (format t "Thread ~A running ~%" *current-thread*)
       (with-mutex (*a-mutex*)
         (format t "Thread ~A got the lock~%" *current-thread*)
         (sleep (random 5)))
       (format t "Thread ~A dropped lock, dying now~%" *current-thread*))
     
     (make-thread #'thread-fn)
     (make-thread #'thread-fn)

— Structure: sb-thread:mutex

Class precedence list: mutex, structure-object, t

Mutex type.

— Function: sb-thread:make-mutex &key name %owner state

Create a mutex.

— Function: sb-thread:mutex-name instance

Name of a queue. Can be assingned to using setf. Queue names can be arbitrary printable objects, and need not be unique.

— Function: sb-thread:mutex-value mutex

Current owner of the mutex, nil if the mutex is free. May return a stale value, use mutex-owner instead.

— Function: sb-thread:get-mutex mutex &optional new-owner waitp

Acquire mutex for new-owner, which must be a thread or nil. If new-owner is nil, it defaults to the current thread. If waitp is non-NIL and the mutex is in use, sleep until it is available.

Note: using get-mutex to assign a mutex to another thread then the current one is not recommended, and liable to be deprecated.

get-mutex is not interrupt safe. The correct way to call it is:

           (WITHOUT-INTERRUPTS
             ...
             (ALLOW-WITH-INTERRUPTS (GET-MUTEX ...))
             ...)

without-interrupts is necessary to avoid an interrupt unwinding the call while the mutex is in an inconsistent state while allow-with-interrupts allows the call to be interrupted from sleep.

It is recommended that you use with-mutex instead of calling get-mutex directly.

— Function: sb-thread:release-mutex mutex &key if-not-owner

Release mutex by setting it to nil. Wake up threads waiting for this mutex.

release-mutex is not interrupt safe: interrupts should be disabled around calls to it.

If the current thread is not the owner of the mutex then it silently returns without doing anything (if if-not-owner is :PUNT), signals a warning (if if-not-owner is :WARN), or releases the mutex anyway (if if-not-owner is :FORCE).

— Macro: sb-thread:with-mutex (mutex &key value wait-p) &body body

Acquire mutex for the dynamic scope of body, setting it to value or some suitable default value if nil. If wait-p is non-NIL and the mutex is in use, sleep until it is available

— Macro: sb-thread:with-recursive-lock (mutex) &body body

Acquires mutex for the dynamic scope of body. Within that scope further recursive lock attempts for the same mutex succeed. It is allowed to mix with-mutex and with-recursive-lock for the same mutex provided the default value is used for the mutex.