щ ает нулевое значение; в противно м случае — код ошибки, обозначающий ее характер.

Ошибки

Функция pthread_once() м ожет завершиться неудачно, если:

[EINVAL] значения, заданные пара м етра м и once_control или init_routine, недействительны. Функция pthread_once() не возвращает код ошибки [EINTR].

Примеры

Отсутствуют.

Замечания по использованию

Отсутствуют.

Логическое обоснование

Некоторые библиотеки С разработаны для дина м ической инициализации. Это означает, что глобальная инициализация для такой библиотеки выполняется при вызове первой библиотечной процедуры. В однопоточной програ мм е это обычно реализуется с использование м статической пере м енной, значение которой проверяется при входе в функцию, напри м ер:

static int random_is_initialized = 0;

extern int initialize_random ();

int random_function () {

if (random_is_initialized == 0) {

initialize_random ();

random_is_initialized = 1;

}

... /* Операции, выполняемые после инициализации. */

}

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

Для динамической инициализации в многопоточном процессе недостаточно простого флага инициализации; этот флаг необходимо защищать от модификации данных со стороны нескольких потоков, одновременно обращающихся к библиотеке. Защита флага требует использования мьютекса, однако мьютексы должны быть инициализированы до их использования. Для гарантии того, что мьютекс инициализируется только единожды, требуется рекурсивное решение этой проблемы.

Использование функции pthread_once () не только предоставляет гарантированные реализацией средства дина м ической инициализации, но и способствует надежному функционированию многопоточных систем реального вре м ени. Предыдущий пример с учетом вышесказанного принимает следующий вид.

#include <pthread.h>

static pthread_once_t random_is_initialized =PTHREAD_ONCE_INIT;

extern int initialize_random();

int random_function()

{

(void) pthread_once (&random_is_initialized,initialize_random); ...

/* Операции, выполняемые после инициализации. */

}

Обратите вни м ание на то, что тип pthread_once_t не может быть массивом, поскольку для некоторых компиляторов конструкция &<array_name> неприемлема.

Будущие направления

Отсутствуют.

Смотри также

Том Base Definitions стандарта1ЕЕЕStd 1003.1-2001, <pthread.h>.

Последовательность внесения изменений

Функции впервые реализованы в выпуске Issue 5. Включены для согласования с расширением POSIX Threads Extension.

Issue 6

Функция pthread_once () от м ечена как часть опции Threads.

Был добавлен код ошибки [EINVAL], возвращаемый при неудачном завершении функции в случае, если хотя бы один из аргументов недействителен.

pthread_rwlock_destroy, pthread_rwlock_init

Имя

pthread_rwlock_destroy, pthread_rwlock_init — функции разрушения и инициализации объекта блокировки для чтения и записи.

Синопсис

THR

#include <pthread.h>

int pthread_rvlock_destroy(pthread_rwlock_t *rwlock);

int pthread_rwlock_init( pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

Описание

Функция pthread_rwlock_destroy() используется для разрушения объекта блокировки чтения и записи, адресуемого параметром rwlock, и освобождения любых ресурсов, задействованных этой блокировкой. Результат последующего использования этой блокировки не определен до тех пор, пока объект не будет инициализирован повторно посредство м еще одного обращения к функции pthread_rwlock_init(). В конкретной реализации функция pthread_rwlock_destroy () может устанавливать объект, адресуемый параметром rwlock, равным недействительному значению. Результаты не определены, если функция pthread_rwlock_destroy() вызывается в то вре м я, когда какой-нибудь поток удерживает объект блокировки, адресуе м ый пара м етром rwlock. Попытка разрушить неинициализированный объект блокировки для чтения и записи приводит к неопределенному поведению.

Функция pthread_rwlock_init() выделяет любые ресурсы, необходимые для использования объекта блокировки для чтения и записи, адресуемого пара м етром rwlock, и инициализирует его (он переходит в незаблокированное состояние) с использованием объекта атрибутов, адресуе м ого пара м етро м attr. Если пара м етр attr содержит значение NULL, для блокировки чтения и записи будут использованы атрибуты, действующие по у м олчанию; т.е. результат в это м случае равносилен передаче адреса объекта, содержащего стандартные атрибуты блокировки для чтения и записи. После первой инициализации объект блокировки можно использовать любое число раз без повторной инициализации. Результаты не определены, если функция pthread_rwlock_init () вызвана с заданием уже инициализированного объекта блокировки. Результаты не определены, если объект блокировки для чтения и записи используется без предварительной инициализации.

При неудачном выполнении функции pthread_rwlock_init() объект, адресуемый параметро м rwlock, остается неинициализированны м, а содержимое параметра rwlock — неопределенным.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату