Необязательные компоненты библиотеки работы с нитями
В данном разделе описаны расширенные атрибуты нитей, взаимных блокировок и переменных условий.
В стандарте библиотек нитей POSIX реализация некоторых компонентов объявлена необязательной. Все функции, определенные с помощью API библиотеки нитей, доступны всегда. Некоторые функции могут быть не реализованы. Приложения могут вызывать нереализованные функции, но такие функции всегда будут возвращать код ошибки ENOSYS.
Атрибуты стека
Для каждой нити выделяется собственный стек. Управление стеком зависит от реализации. Таким образом, приведенная ниже информация применима только к AIX, хотя подобные функции могут существовать и в других системах.
Стек выделяется динамически при создании нити. С помощью расширенных атрибутов нити пользователь может управлять размером стека и задавать его адрес. Приведенная ниже информация не относится к начальной нити, создаваемой системой.
Размер стека
С помощью размера стека можно изменять значение атрибута stacksize в объекте атрибутов нити. Этот атрибут указывает минимальный размер области памяти, отведенной под стек для вновь созданной нити.
- Атрибут stacksize из объекта атрибутов нити
- Функция pthread_attr_getstacksize возвращает значение атрибута
- Функция pthread_attr_setstacksize задает значение атрибута
Значение атрибута stacksize по умолчанию равно 96 Кб. Минимальное значение атрибута stacksize по умолчанию равно 16 Кб. Если указанное значение меньше минимального, то будет применяться минимальное значение.
- Красная зона, защищенная от чтения и записи, предназначена для обнаружения переполнения стека. В программах с большими страницами красная зона не предусмотрена.
- Стек по умолчанию.
- Структура pthread.
- Структура thread.
- Структура атрибутов thread.
Адрес стека компонента POSIX
С адресом стека связано значение атрибута stackaddr в объекте атрибутов нити. Этот атрибут указывает место в памяти, отведенное под стек для вновь созданной нити.
- Атрибут stackaddr задает адрес стека, выделяемого нити.
- Функция pthread_attr_getstackaddr возвращает значение атрибута.
- Функция pthread_attr_setstackaddr задает значение атрибута.
Если адрес не указан, то нити выделяется стек с произвольным адресом. Если стек необходимо определить по конкретному адресу, то вы можете воспользоваться атрибутом stackaddr. Например, если нужен стек очень большого размера, вы можете указать для него адрес из свободного сегмента.
Если адрес стека был указан при вызове функции pthread_create, то система попытается выделить стек по этому адресу. Если сделать это невозможно, то функция pthread_create вернет значение EINVAL. Функция pthread_attr_setstackaddr возвращает ошибку только в том случае, если указанный адрес стека не попадает в адресное пространство.
Планирование приоритета компонента POSIX
Планирование приоритета позволяет управлять планированием нитей. Если эта функция отключена, то параметры планирования всех нитей в процессе наследуются от самого процесса. Если же она включена, то каждая нить имеет свой набор параметров планирования. Для нитей с локальной областью действия с параметрами планирования работает планировщик библиотеки на уровне процесса, в то время как параметры планирования нитей с глобальной областью действия обрабатывает планировщик ядра на системном уровне.
Если этот необязательный компонент реализован, то доступны следующие атрибуты и функции:
- Атрибут inheritsched из объекта атрибутов нити
- Атрибут schedparam из объекта атрибутов нити и из самой нити
- Атрибут schedpolicy из объекта атрибутов нити и из самой нити
- Атрибут contention-scope из объекта атрибутов нити и из самой нити
- Функции pthread_attr_getschedparam и pthread_attr_setschedparam
- Функция pthread_getschedparam
Проверка наличия необязательного компонента
Проверить наличие необязательных компонентов можно как на этапе компиляции, так и на этапе выполнения. Переносимые программы должны проверять наличие необязательных компонентов до начала работы с ними, чтобы не приходилось изменять исходный код программ при переносе в другую систему.
Проверка во время компиляции
#ifndef _POSIX_THREAD_ATTR_STACKSIZE
#error "Необходимо наличие компонента POSIX - Размер стека"
#endif- _POSIX_REENTRANT_FUNCTIONS
- Означает, что необходимы реентерабельные функции.
- _POSIX_THREADS
- Означает реализацию библиотеки нитей.
Проверка во время выполнения
Для проверки наличия необязательных компонентов в системе на этапе выполнения программы можно применять функцию sysconf. Она оказывается весьма полезной при переносе программ в двоично-совместимую систему, например, в систему под управлением другой версии AIX.
Ниже приведен список символьных констант, связанных со всеми необязательными компонентами. Эти символьные константы необходимо передать в функцию sysconf в параметре Name. Константы определены в файле заголовка unistd.h.
- Адрес стека
- _SC_THREAD_ATTR_STACKADDR
- Размер стека
- _SC_THREAD_ATTR_STACKSIZE
- Планирование приоритета
- _SC_THREAD_PRIORITY_SCHEDULING
- Наследование приоритета
- _SC_THREAD_PRIO_INHERIT
- Защита приоритета
- _SC_THREAD_PRIO_PROTECT
- Совместное выполнение процессов
- _SC_THREAD_PROCESS_SHARED
- _SC_REENTRANT_FUNCTIONS
- Означает, что необходимы реентерабельные функции.
- _SC_THREADS
- Означает реализацию библиотеки нитей.
Совместное выполнение процессов
В AIX и большинстве систем UNIX допускается использование несколькими процессами одного пространства данных, называемого общей памятью. Атрибуты совместного выполнения процессов, задаваемые для переменных условий и взаимных блокировок, позволяют размещать эти объекты в общей памяти для синхронизации нитей различных процессов. Однако стандартного интерфейса управления общей памятью не существует, поэтому опция POSIX для общих процессов в AIX не реализована.
Типы данных библиотеки нитей
- pthread_t
- Идентифицирует нить.
- pthread_attr_t
- Идентифицирует объект атрибутов нити.
- pthread_cond_t
- Идентифицирует условную переменную.
- pthread_condattr_t
- Идентифицирует объект атрибутов условной переменной.
- pthread_key_t
- Идентифицирует ключ данных для конкретной нити.
- pthread_mutex_t
- Идентифицирует взаимную блокировку.
- pthread_mutexattr_t
- Идентифицирует объект атрибутов взаимной блокировки.
- pthread_once_t
- Идентифицирует объект разовой инициализации.
Ограничения и значения по умолчанию
- В процессе не может быть более 512 нитей. Максимальное количество нитей можно получить на этапе компиляции с помощью символьной константы PTHREAD_THREADS_MAX, определенной в файле заголовка pthread.h. Если приложение скомпилировано с флагом -D_LARGE_THREADS, то максимальное число нитей в одном процессе равно 32767.
- Минимальный размер стека для одной нити
составляет 8 Кб. По умолчанию размер стека равен 96 Кб. Минимальный
размер стека можно получить на этапе компиляции с помощью символьной
константы PTHREAD_STACK_MIN, определенной в файле заголовка
pthread.h. Прим.: Максимальный размер стека составляет 256 Мб, что равно размеру сегмента. Это ограничение можно получить с помощью символьной константы PTHREAD_STACK_MAX в файле заголовка pthread.h.
- Максимальное значение этого параметра - 508. Это значение можно получить на этапе компиляции с помощью символьной константы PTHREAD_KEYS_MAX, определенной в файле заголовка pthread.h.
Значения атрибутов по умолчанию
- Значение символьной константы DEFAULT_DETACHSTATE по умолчанию равно PTHREAD_CREATE_DETACHED и задает значение атрибута detachstate по умолчанию.
- Значение символьной константы DEFAULT_JOINABLE по умолчанию равно PTHREAD_CREATE_JOINABLE и задает значение объединяемого состояния по умолчанию.
- Значение символьной константы DEFAULT_INHERIT по умолчанию равно PTHREAD_INHERIT_SCHED и задает значение атрибута inheritsched по умолчанию.
- Значение символьной константы DEFAULT_PRIO по умолчанию равно 1 и задает значение по умолчанию для поля sched_prio атрибута schedparam.
- Значение символьной константы DEFAULT_SCHED по умолчанию равно SCHED_OTHER и задает значение атрибута нитей schedpolicy по умолчанию.
- Значение символьной константы DEFAULT_SCOPE по умолчанию равно PTHREAD_SCOPE_LOCAL и задает значение атрибута contention-scope по умолчанию.