pthread_mutex_lock()

Заблокировать мьютекс

Прототип:

#include <pthread.h>
int pthread_mutex_lock( pthread_mutex_t *mutex );

Аргументы:

mutex
Указатель на объект pthread_mutex_t, который необходимо заблокировать.

Библиотека:

libc

Описание:

Функция pthread_mutex_lock() блокирует мьютекс mutex. Если мьютекс уже заблокирован, то вызывающий поток блокируется до тех пор, пока он не захватит мьютекс. По возвращении из функции, объект мьютекса блокируется и принадлежит вызывающему потоку.

Поведение этой функции при попытке заблокировать уже принадлежащий вам мьютекс зависит от типа мьютекса. Для получения дополнительной информации см. pthread_mutexattr_settype().

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

Если мьютекс является рекурсивным, следует вызывать pthread_mutex_unlock() для каждого соответствующего вызова, чтобы заблокировать мьютекс.

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

Если перед инициализацией мьютекса была вызвана функция pthread_mutexattr_setwakeup_np() для включения "пробуждения", можно позже вызвать pthread_mutex_wakeup_np(), чтобы "разбудить" любые потоки, заблокированные на мьютексе. Постфикс «np» в именах этих функций означает «не-POSIX».

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

EOK
Успешное завершение.
EAGAIN
Недостаточно системных ресурсов для блокировки мьютекса.
EDEADLK
Вызывающий поток уже владеет mutex, а мьютекс не допускает рекурсивного поведения.
EFAULT
Произошла ошибка, когда ядро попыталось получить доступ к предоставленным буферам.
EINTR
(расширение ЗОСРВ «Нейтрино») Поток был разблокирован вызовом pthread_mutex_wakeup_np().
EINVAL
Некорректный мьютекс mutex.
ETIMEDOUT
Тайм-аут ядра разблокировал вызов.

Примеры:

В данном примере показано, как можно использовать мьютекс для синхронизации доступа к общей переменной. В этом примере function1() и function2() пытаются получить доступ и изменить глобальную переменную count. Любой поток может быть прерван между изменением счетчика и присвоением его значения локальной переменной tmp. Блокировка mutex предотвращает это; если один поток заблокировал mutex, другой поток ждет, пока он не будет разблокирован, прежде чем продолжить.

#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int count = 0;
void * function1( void *arg )
{
int tmp = 0;
while ( 1 )
{
pthread_mutex_lock( &mutex );
tmp = count++;
pthread_mutex_unlock( &mutex );
printf( "Count is %d\n", tmp );
/* snooze for 1 second */
sleep( 1 );
}
return (0);
}
void * function2( void *arg )
{
int tmp = 0;
while ( 1 )
{
pthread_mutex_lock( &mutex );
tmp = count--;
pthread_mutex_unlock( &mutex );
printf( "** Count is %d\n", tmp );
/* snooze for 2 seconds */
sleep( 2 );
}
return (0);
}
int main( void )
{
pthread_create( NULL, NULL, &function1, NULL );
pthread_create( NULL, NULL, &function2, NULL );
/* Let the threads run for 60 seconds. */
sleep( 60 );
return (0);
}

Классификация:

POSIX 1003.1 Threads

Безопасность использования
Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

pthread_mutex_init(), pthread_mutex_timedlock(), pthread_mutex_trylock(), pthread_mutex_unlock(), pthread_mutex_wakeup_np(), pthread_mutexattr_setrecursive(), pthread_mutexattr_settype(), pthread_mutexattr_setwakeup_np() SyncMutexLock()




Предыдущий раздел: Описание API системной библиотеки