Монитор позволяет две разные вещи:
- взаимное исключение - не более одного потока может владеть монитором в любой момент времени
- сотрудничество - поток, владеющий монитором, может подождать, пока он не будет пробужден взаимодействующим потоком, посредством уведомления, отправленного через монитор
Библиотека потоков Posix разделяет эти две проблемы на два разных объекта:
- взаимное исключение осуществляется с помощью мьютекса
- сотрудничество осуществляется с помощью условной переменной
Предполагается, что сотрудничество касается некоторого состояния, разделяемого между потоками. Ожидается, что это состояние будет защищено мьютексом. Таким образом, базовая операция ожидания принимает два аргумента:
- переменная условия для ожидания уведомления (сигнализации) на
- мьютекс, защищающий разделяемое состояние
Когда поток ожидает переменную условия с использованием мьютекса, мьютекс освобождается и поток переводится в спящий режим. Когда поток пробудится, он снова получит мьютекс перед продолжением.
Сигнализация (уведомление одного потока) или передача (уведомление всех потоков) условной переменной не требует мьютекса.
Переменные условия предназначены исключительно для этого использования. Их можно использовать в качестве команды "ненадолго спать и отпускать этот мьютекс, пока вы спите", используя закрытую переменную условия, которая никогда не сигнализируется, и время ожидания (pthread_cond_timedwait()
).