pthread_once
Имя
pthread_once — функция д ина м ической инициализации пакетов.
Синопсис
THR #include <pthread.h>
int pthread_once (pthread_once_t *once_control, void (*init_rout_ne) (void)); pthread_once_t once_control = PTHREAD_ONCE_INIT;
Описание
При перво м обра щ ении к функции pthread_once() любы м потоко м процесса с заданны м пара м етро м once_control будет вызвана функция ini t_routine без аргументов. Последующие обра щ ения к функции pthread_once () с те м же пара м етро м once_control не вызывают функцию init_routin e. Возвра щ ение из функции pthread_once() означает, что функция init_routine выполнена. Пара м етр once_control определяет, вызываласьли соответствую щ ал функция инициализации.
Функция pthread_once () не является точкой от м ены. Но если функция init_routine является точкой от м ены, и от м ена таки происходит, то ее воздействие на пара м етр once_control будет таки м, как если бы функция pthread_once () никогда не вызывалась.
Константа PTHREAD_ONCE_INIT определяется в заголовке <pthread. h>.
Поведение функции pthread_once () будет неопределенны м, если пара м етр once_control и м еет авто м атический класс па м яти (объекты этого класса раз м е щ аются в стеке и инициализируются всякий раз при входе в блок, где они объявлены, иразрушаются при выходе из этого блока) или не инициализирован константой PTHREAD_ONCE_INIT.
Возвращаемое значение
При успешно м завершении функция 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], возвращаемый при неудачном завершении функции в случае, если хотя бы один из аргументов недействителен.
Больше книг — больше знаний!
Заберите 30% скидку новым пользователям на все книги Литрес с нашим промокодом
ПОЛУЧИТЬ СКИДКУ