Скачиваний:
90
Добавлен:
12.05.2015
Размер:
913.92 Кб
Скачать

15.5. Атрибуты средств синхронизации потоков

В наших примерах в этой главе мы хранили взаимные исключения, условные переменные и блокировки чтения-записи как глобальные данные всего процесса, поскольку они использовались для синхронизации потоков внутри него. Инициализировали мы их с помощью трех констант: PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZERи PTHREAD_RWLOCK_INITIALIZERсоответственно. Инициализируемые таким образом средства синхронизации потоков приобретали значения атрибутов по умолчанию, но мы можем инициализировать их и с другими значениями атрибутов.

15.5.1. Атрибуты взаимных исключений

Атрибуты взаимного исключения имеют тип pthread_mutexattr_t. Они инициализируются и разрушаются с помощью двух указанных ниже функций.

#include<pthread.h>

int pthread_mutexattr_init (pthread_mutexattr_t *attr);

int pthread_mutexattr_destroy (pthread_mutexattr_t *attr);

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

Функция pthread_mutexattr_initинициализирует структуруpthread_mutexattr_t, содержащую атрибуты взаимного исключения, значениями по умолчанию. Здесь представляют интерес два атрибута:process_sharedиtype. Согласно стандарту Posix.1 атрибутprocess_sharedявляется необязательным. Если он поддерживается в конкретной операционной системе, то будет определен и символ_POSIX_THREAD_PROCESS_SHARED.

Внутри процесса множество потоков могут иметь доступ к одному и тому же объекту синхронизации. Такое поведение определено по умолчанию. В этом случае атрибут взаимного исключения process_sharedимеет значениеPTHREAD_PROCESS_PRIVATE.

Как мы увидим в главе 20, существуют механизмы, позволяющие независимым друг от друга процессам (родственникам?) отображать одну и ту же область памяти в свои собственные адресные пространства. Доступ к данным, совместно используемым несколькими процессами, обычно требует синхронизации, так же как и доступ к совместно используемым данным из нескольких потоков. Если атрибутуprocess_sharedприсвоено значениеPTHREAD_PROCESS_SHARED, то взаимное исключение может быть размещено в области памяти, разделяемой между несколькими процессами, и использоваться для синхронизации действий этих процессов.

Получить значение атрибута process_sharedструктурыpthread_mutexattr_tможно с помощью функцииpthread_mutexattr_getpshared. Чтобы установить значение этого атрибута, следует использовать функциюpthread_mutexattr_setpshared.

#include<pthread.h>

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

int pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared);

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

Атрибут typeпозволяет указать тип взаимного исключения. Стандарт Posix.1 определяет четыре типа. ТипPTHREAD_MUTEX_NORMAL – это стандартное взаимное исключение, которое не проверяет наличие ошибок или тупиковых ситуаций. Взаимные исключения типаPTHREAD_MUTEX_ERRORCHECKпроизводят проверку наличия ошибок.

Взаимные исключения типа PTHREAD_MUTEX_RECURSIVEпозволяют одному и тому же потоку многократно запирать взаимное исключение, не отпирая его. Рекурсивные взаимные исключения содержат счетчик, который хранит количество запираний взаимного исключения. Взаимное исключение будет свободно только тогда, когда количество отпираний совпадет с количеством запираний. Так, если имеется рекурсивное взаимное исключение, которое было заперто дважды, а отперто всего лишь один раз, то оно все равно останется занятым до тех пор, пока не будет отперто еще один раз.

И, наконец, взаимные исключения типа PTHREAD_MUTEX_DEFAULTмогут использоваться для назначения модели поведения по умолчанию для взаимных исключений. Реализации могут самостоятельно определять, какой из трех описанных выше типов взаимных исключений выбрать как тип по умолчанию. Так, например, в ОС Linux в качестве типа взаимного исключения по умолчанию выбран типPTHREAD_MUTEX_NORMAL.

Чтобы получить значение атрибута type, можно использовать функциюpthread_mutexattr_gettype. Чтобы установить значение этого атрибута, следует использовать функциюpthread_mutexattr_settype.

#include<pthread.h>

int pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type);

int pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type);

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

Таблица 15.1

Соседние файлы в папке Chapter.4