Читать «UNIX: взаимодействие процессов» онлайн - страница 120

Уильям Ричард Стивенс

#include <pthread.h>

int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *valptr);

int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int value);

int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *valptr);

int pthread_condattr_setpshared(pthread_condattr_t *attr, int value);

/* Все четыре функции возвращают 0 в случае успешного завершения, положительное значение Еххх – в случае ошибки */

Две функции get возвращают текущее значение атрибута через целое, на которое указывает valptr, а две функции set устанавливают значение атрибута равным значению value. Значение value может быть либо PTHREAD_PROCESS_PRIVATE, либо PTHREAD_PROCESS_SHARED. Последнее также называется атрибутом совместного использования процессами. 

ПРИМЕЧАНИЕ

Эта возможность поддерживается только в том случае, если константа _POSIX_THREAD_PROCESS_SHARED определена в заголовочном файле <unistd.h>. Она является дополнительной согласно Posix.1 и обязательной по Unix 98 (табл. 1.3). 

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

pthread_mutex_t *mptr; /* указатель на взаимное исключение, находящееся в разделяемой памяти */

pthread_mutexattr_t mattr; /* атрибуты взаимного исключения */

mptr = /* некоторое значение, указывающее на разделяемую память */

Pthread_mutexattr_init(&mattr);

#ifdef _POSIX_THREAD_PROCESS_SHARED

 Pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);

#else

 # error Эта реализация не поддерживает _POSIX_THREAD_PROCESS_SHARED

#endif

Pthread_mutex_init(mptr, &mattr);

Мы объявляем переменную mattr типа pthread_mutexattr_t, инициализируем ее значениями атрибутов по умолчанию, а затем устанавливаем атрибут PTHREAD_PROCESS_SHARED, позволяющий совместно использовать взаимное исключение нескольким процессам. Затем pthread_mutex_init инициализирует само исключение с соответствующими атрибутами. Количество разделяемой памяти, которое следует выделить под взаимное исключение, равно sizeof(pthread_mutex_t).

Практически такая же последовательность команд (с заменой mutex на cond) позволяет установить атрибут PTHREAD_PROCESS_SHARED для условной переменной, хранящейся в разделяемой несколькими процессами памяти.

Пример совместно используемых несколькими процессами взаимных исключений и условных переменных был приведен в листинге 5.18.

Завершение процесса, заблокировавшего ресурс

Когда взаимное исключение используется совместно несколькими процессами, всегда существует возможность, что процесс будет завершен (возможно, принудительно) во время работы с заблокированным им ресурсом. Не существует способа заставить систему автоматически снимать блокировку во время завершения процесса. Мы увидим, что это свойственно и блокировкам чтения-записи, и семафорам Posix. Единственный тип блокировок, автоматически снимаемых системой при завершении процесса, — блокировки записей fcntl (глава 9). При использовании семафоров System V можно специально указать ядру, следует ли автоматически снимать блокировки при завершении работы процесса (функция SEM_UNDO, о которой будет говориться в разделе 11.3).