7.7. Атрибуты взаимных исключений и условных переменных
7.7. Атрибуты взаимных исключений и условных переменных
В наших примерах в этой главе мы хранили взаимные исключения и условные переменные как глобальные данные всего процесса, поскольку они использовались для синхронизации потоков внутри него. Инициализировали мы их с помощью двух констант: PTHREAD_MUTEX_INITIALIZER и PTHREAD_COND_INTIALIZER. Инициализируемые таким образом исключения и условные переменные приобретали значения атрибутов по умолчанию, но мы можем инициализировать их и с другими значениями атрибутов.
Прежде всего инициализировать и удалять взаимное исключение и условную переменную можно с помощью функций
#include <pthread.h>
int pthread_mutex_imt(pthread_mutex_t *mptr, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mptr);
int pthread_cond_init(pthread_cond_t *cрtr, const pthread_condattr_t *attr);
int pthread_cond_destroy(pthread_cond_t *cptr);
/* Все четыре функции возвращают 0 в случае успешного завершения работы, положительное значение Еххх – в случае ошибки */
Рассмотрим, например, взаимное исключение. Аргумент mptr должен указывать на переменную типа pthread_mutex_t, для которой должна быть уже выделена память, и тогда функция pthread_mutex_init инициализирует это взаимное исключение. Значение типа pthread_mutexattr_t, на которое указывает второй аргумент функции pthread_mutex_init(attr ), задает атрибуты этого исключения. Если этот аргумент представляет собой нулевой указатель, используются значения атрибутов по умолчанию.
Атрибуты взаимного исключения имеют тип pthread_mutexattr_t, а условной переменной — pthread_condattr_t, и инициализируются и уничтожаются с помощью следующих функций:
#include <pthread.h>
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
int pthread_condattr_destroy(pthread_condattr_t *attr);
/* Все четыре функции возвращают 0 в случае успешного завершения, положительное значение Еххх – в случае ошибки */
После инициализации атрибутов взаимного исключения или условной переменной для включения или выключения отдельных атрибутов используются отдельные функции. Например, один из атрибутов позволяет использовать данное взаимное исключение или условную переменную нескольким процессам (а не потокам одного процесса). Этот атрибут мы будем использовать в последующих главах. Его значение можно узнать и изменить с помощью следующих функций:
#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.
Данный текст является ознакомительным фрагментом.