Параллельное и распределенное программирование на С++
Шрифт:
Возвращаемое значение
При успешно м завершении функция pthread_once возвра щ ает нулевое значение; в противно м случае — код ошибки, обозначающий ее характер.
Ошибки
Функция 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 — неопределенным.
Для выполнения синхронизации можно использовать только объект, адресуемый параметром rwlock. Результат ссылки на копии этого объекта в вызовах функций pthread_rwlock_destroy, pthread_rwlock_rdlock, pthread_rwlock_ti~ medrdlock, pthread_rwlock_timedwrlock, pthread_rwlock_tryrdlock, pthread_rwlock_trywrlock , pthread_rwlock_unlock или pthread_rwlock_ wrlock не опре д елен.