Статические инициализаторы для мьютексов и условных переменных
Обеспечение статической инициализации статически размещаемых в памяти объектов синхронизации позволяет в модулях, содержащих закрытые статические переменные синхронизации, избежать тестирования и соответствующих затрат, связанных с динамической инициализацией. Более того, это упрощает кодирование модулей самоинициализации . Такие модули широко используются в библиотеках, в которых по различным причинам вместо явного вызова функций инициализации используется самоинициализация. Ниже приводится пример использования статической инициализации.
Без применения статической инициализации функция самоинициализации foo () может иметь следующий вид.
>static pthread_once_t foo_once = PTHREAD_ONCE_INIT;
>static pthread_mutex_t foo_mutex;
>void foo_init () {
> pthread_mutex_init (&foo_mutex, NULL);
>}
>void foo() {
>pthread_once(&foo_once, foo_init);
>pthread_mutex_lock (&foo_mutex);
>/* Выполнение действий. */
>pthread_mutex_unlock (&foo_mutex);
>}
С применением статической инициализации ту же функцию самоинициализации foo() м ожно было бы закодировать таки м образо м.
>static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;
>void foo()
>{
>pthread_mutex_lock(&foo_mutex) ;
>/* Выполнение действий. */
>pthread_mutex_unlock(&foo_mutex);
>}
Обратите внимание на то, что статическая инициализация устраняет необходимость в тестировании, проводимом в функции pthread_once (), и получении значения адреса &foo_mutex, передаваемого функции pthread_mutex_lock() или pthread_mutex_unlock ().
Таким образом, С-код, написанный для инициализации статических объектов, проще во всех системах и работает быстрее на большом классе систем, в которых объект (внутренней) синхронизации можно хранить в памяти приложения.
До сих пор вопрос о быстродействии блокировок поднимался для машин, которые требовали, чтобы для мьютексов выделялась специальная память. В действительности в таких машинах мьютексы и, возможно, условные переменные должны были содержать указатели на реальные аппаратные средства защиты. Для того чтобы на таких машинах работала статическая инициализация, функция pthread_mutex_lock () также должна проверять, выделена ли память для указателя на реальный объект блокировки. Если не выделена, функция pthread_mutex_lock (), прежде чем его использовать, должна его инициализировать. Резервирование таких ресурсов можно выполнить при загрузке программы, и поэтому для мьютексов и условных переменных не были введены дополнительные коды ошибок, означающие неудачное выполнение инициализации.