Параллельное и распределенное программирование на С++ (Хьюз, Хьюз) - страница 432

Статические инициализаторы для мьютексов и условных переменных

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

Без применения статической инициализации функция самоинициализации 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 (), прежде чем его использовать, должна его инициализировать. Резервирование таких ресурсов можно выполнить при загрузке программы, и поэтому для мьютексов и условных переменных не были введены дополнительные коды ошибок, означающие неудачное выполнение инициализации.