40.3 Условные переменные

Условная переменная — это способ для потока заблокироваться до наступления некоторого события. Поток может ожидать на условной переменной, чтобы быть разбуженным, когда другой поток уведомит это условие.

Условная переменная связана с мьютексом и, концептуально, с некоторым условием. Для правильной работы мьютекс должен быть захвачен, а затем ожидающий поток должен выполнять цикл, проверяя условие и ожидая на условной переменной. Например:

(with-mutex mutex
  (while (not global-variable)
    (condition-wait cond-var)))

Мьютекс обеспечивает атомарность, а цикл нужен для надёжности — возможны ложные уведомления.

Аналогично, мьютекс должен быть захвачен перед уведомлением условия. Типичный и наилучший подход — захватить мьютекс, внести изменения, связанные с этим условием, а затем уведомить о нём:

(with-mutex mutex
  (setq global-variable (some-computation))
  (condition-notify cond-var))
Функция: make-condition-variable mutex &optional name

Создаёт новую условную переменную, связанную с mutex. Если указан name, это имя, присваиваемое условной переменной. Оно должно быть строкой. Имя предназначено только для целей отладки; оно не имеет никакого значения для Emacs.

Функция: condition-variable-p object

Эта функция возвращает t, если object представляет условную переменную, и nil в противном случае.

Функция: condition-wait cond

Ожидает, пока другой поток не уведомит cond, условную переменную. Эта функция блокируется до тех пор, пока условие не будет уведомлено, или пока в этот поток не будет доставлен сигнал с помощью thread-signal.

Вызов condition-wait без захвата связанного с условием мьютекса является ошибкой.

condition-wait освобождает связанный мьютекс на время ожидания. Это позволяет другим потокам захватывать мьютекс для уведомления условия.

Функция: condition-notify cond &optional all

Уведомляет cond. Мьютекс, связанный с cond, должен быть захвачен перед вызовом этой функции. Обычно condition-notify пробуждает один ожидающий поток; но если all не равен nil, то уведомляются все потоки, ожидающие на cond.

condition-notify освобождает связанный мьютекс. Это позволяет другим потокам захватывать мьютекс для ожидания условия.

Функция: condition-name cond

Возвращает имя cond, переданное в make-condition-variable.

Функция: condition-mutex cond

Возвращает мьютекс, связанный с cond. Обратите внимание, что связанный мьютекс не может быть изменён.