Читать «UNIX: взаимодействие процессов» онлайн - страница 120
Уильям Ричард Стивенс
#include <pthread.h>
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *
int pthread_mutexattr_setpshared(pthread_mutexattr_t *
int pthread_condattr_getpshared(const pthread_condattr_t *
int pthread_condattr_setpshared(pthread_condattr_t *
/* Все четыре функции возвращают 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).