Next: , Previous: Mutex Support, Up: Threading


11.4 Waitqueue/condition variables

These are based on the POSIX condition variable design, hence the annoyingly CL-conflicting name. For use when you want to check a condition and sleep until it's true. For example: you have a shared queue, a writer process checking “queue is empty” and one or more readers that need to know when “queue is not empty”. It sounds simple, but is astonishingly easy to deadlock if another process runs when you weren't expecting it to.

There are three components:

Important stuff to be aware of:

     (defvar *buffer-queue* (make-waitqueue))
     (defvar *buffer-lock* (make-mutex :name "buffer lock"))
     
     (defvar *buffer* (list nil))
     
     (defun reader ()
       (with-mutex (*buffer-lock*)
         (loop
          (condition-wait *buffer-queue* *buffer-lock*)
          (loop
           (unless *buffer* (return))
           (let ((head (car *buffer*)))
             (setf *buffer* (cdr *buffer*))
             (format t "reader ~A woke, read ~A~%"
                     *current-thread* head))))))
     
     (defun writer ()
       (loop
        (sleep (random 5))
        (with-mutex (*buffer-lock*)
          (let ((el (intern
                     (string (code-char
                              (+ (char-code #\A) (random 26)))))))
            (setf *buffer* (cons el *buffer*)))
          (condition-notify *buffer-queue*))))
     
     (make-thread #'writer)
     (make-thread #'reader)
     (make-thread #'reader)

— Structure: sb-thread:waitqueue

Class precedence list: waitqueue, structure-object, t

Waitqueue type.

— Function: sb-thread:make-waitqueue &key name

Create a waitqueue.

— Function: sb-thread:waitqueue-name instance

The name of the waitqueue. Setfable.

— Function: sb-thread:condition-wait queue mutex

Atomically release mutex and enqueue ourselves on queue. Another thread may subsequently notify us using condition-notify, at which time we reacquire mutex and return to the caller.

— Function: sb-thread:condition-notify queue &optional n

Notify n threads waiting on queue.

— Function: sb-thread:condition-broadcast queue

Notify all threads waiting on queue.