Выбрать главу

Для мьютексов типа PTHREAD_MUTEX_ERRORCHECK предусмотрена проверка на наличие ошибок. Если поток попытается заблокировать мьютекс, который уже заблокирован, возвращается ошибка. Если поток попытается разблокировать мьютекс, который не заблокирован, возвращается ошибка.

Если мьютекс имеет тип PTHREAD_MUTEX_RECURSIVE, мьютекс должен поддерживать концепцию подсчета блокировок. При первом успешном блокировании мьютекса счетчик блокировок устанавливается равным единице. При каждом очередном блокировании этого мьютекса счетчик блокировок инкрементируется, а при каждом разблокировании — декрементируется. Когда счетчик блокировок достигает нулевого значения, мьютекс становится доступным для других потоков. Если поток попытается разблокировать мьютекс, который не заблокирован, возвращается ошибка.

Если м ьютекс и м еет тип PTHREAD_MUTEX_DEFAULT, попытка рекурсивно заблокировать мьютекс приводит к неопределенному поведению. Попытка разблокировать мьютекс, который не был заблокирован (любым потоком, включал вызывающий), приводит к неопределенному поведению.

Функция pthread_mutex_trylock () эквивалентна функции

pthread_mutex_lock (), за исключением того, что если объект мьютекса, адресуемый параметром mutex, в данный момент заблокирован (любым потоком, включал текущий), эта функция немедленно завершится. Если мьютекс имеет тип PTHREAD_MUTEX_RECURSIVE , и в данный момент мьютексом владеет вызывающий поток, счетчик блокировок этого мьютекса инкрементируется, а функция pthread_mutex_trylock () немедленно возвращает признак успешного завершения.

Функция pthread_mutex_unlock () освобождает объект м ьютекса, адресуе м ый пара м етро м mutex.

XSI  Способ освобождения зависит от атрибута типа м ьютекса.

Если при вызове функции pthread_mutex_unlock (), в результате которого мьютекс стал доступным, существуют потоки, заблокированные по объекту мьютекса, адресуемому параметром мьютекс, то поток-владелец этого мьютекса будет установлен стратегией планирования. XSI  

(Для м ьютексов типа PTHREAD_MUTEX_RECURS IVE: м ьютекс становится доступным, когда счетчик блокировок достигает нуля, и вызывающий поток больше не имеет никаких блокировок по этому мьютексу.)

Если к потоку, ожидающему освобождения мьютекса, поступает сигнал, то после выполнения обработчика этого сигнала поток снова перейдет в состояние ожидания, как если бы он и не прерывался на обработку сигнала.

Возвращаемые значения

При успешном завершении функции pthread_mutex_lock() npthread_mutex_unlock() возвращают нулевое значение; в противном случае — код ошибки, обозначающий ее характер.

Функция pthread_mutex_trylock () возвращает нулевое значение, если выполнена блокировка по объекту мьютекса, адресуемому параметром mutex. В противном случае возвращается код ошибки, обозначающий ее характер.

Ошибки

Функции pthread_mutex_lock () и pthread_mutex_trylock () завершатся неудачно, если:

[EINVAL] мьютекс был создан с использованием атрибута protocol, имеющего значение PTHREAD_PRIO_PROTECT, а приоритет вызывающего потока выше текущего значения предельного приоритета мьютекса.

Функция pthread_mutex_trylock () завершится неудачно, если:

[EBUSY] мьютекс остался недоступным, поскольку он был уже заблокирован.

Функции pthread_mutex_lock() , pthread_mutex_trylock()

и pthread_mutex_unlock () м огут завершиться неудачно, если:

[EINVAL] значение, заданное пара м етро м mutex, не относится к инициализированно м у объекту м ьютекса;

XSI [EAGAIN] мьютекс остался недоступным, поскольку было превышено максимальное количество рекурсивных блокировок для мью-текса, заданного параметром mutex.

Функция pthread_mutex_lock () м ожет завершиться неудачно, ес л и:

[ EDEADLK ]  текущий поток уже владеет мьютексом.

Функция pthread_mutex_unlock () м ожет завершиться неудачно, ес л и:

[ EPERM ]  текущий поток не владеет мьютексом.

Эти функции не возвра щ ают код ошибки [EINTR].

Примеры

Отсутствуют.

Замечания по использованию

Отсутствуют.

Логическое обоснование

Объекты мьютексов служат в качестве базовых элементов низкого уровня, на основе которых можно построить другие функции синхронизации потоков. Поэтому реализация мьютексов должна быть максимально эффективной.