Чтение онлайн

на главную - закладки

Жанры

Параллельное и распределенное программирование на С++
Шрифт:

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

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

В качестве альтернативного варианта (в зависимости от архитектуры компьютера) можно в наиболее важных случаях ликвидировать все расходы системных ресурсов на операции блокировки, которые выполняются после инициализации средств блокировки. Это можно сделать путем перехода от более затратных к редко выполняемым операциям, т.е. перенести весь «груз расходов» на однократно выполняемую инициализацию. Поскольку «внешняя» (т.е. выполняемая вне основной программы) инициализация мьютекса также означает, что для получения реальной блокировки адрес должен быть разыменован, один из широко применяемых методов при статической инициализации состоит в сохранении фиктивного значения для этого адреса; в частности, адреса, который вызывает сбой в работе компьютера. При возникновении такого сбоя во время первой попытки заблокировать мьютекс можно сделать проверку достоверности, а затем для реальной блокировки использовать корректный адрес. Последующие операции, связанные с блокировкой, не будут сопряжены с дополнительными расходами, поскольку они уже не являются «сбойными». Это — всего лишь метод, который можно использовать для поддержки статической инициализации, несмотря на то, что он неблагоприятно отражается на скорости захвата блокировки. Безусловно, существуют и другие методы, которые в высокой степени зависят от архитектуры компьютера.

Расходы на блокировку для компьютеров, выполняющих «внешнюю» инициализацию мьютекса, сравнимы с расходами для модулей, инициализируемых неявным образом (имеются в виду те из них, где достигнута «внутренняя» инициализация мьютексов). Безусловно, «внутренняя» инициализация выполняется гораздо быстрее, но «внешняя» ненамного хуже.

Помимо вопроса быстродействия блокировки, нас беспокоит то, что потоки могут соперничать за блокировки при попытке завершить

инициализацию статически размещаемых в памяти мьютексов. (Такое завершение обычно включает захват внутренней блокировки, выделение памяти для структуры, сохранение указателя на эту структуру в мьютексе и освобождение внутренней блокировки.) Во-первых, многие реализации могут сократить эту последовательность действий путем хеширования по адресу мьютекса. Во-вторых, количество таких «сериалов» может быть весьма ограниченным. В частности, их может быть столько, сколько создается статически размещаемых объектов синхронизации. Динамически же создаваемые объекты по-прежнему инициализируются с помощью функций pthread_mutex_init или pthread_cond_init .

Наконец, если ни один из описанных выше методов оптимизации для «внешнего» размещения объектов синхронизации не позволяет достичь нужной производительности приложения при использовании определенной реализации, приложение может избежать статической инициализации, явным образом инициализируя все объекты синхронизации c помощью соответствующих функций pthread_*_init, которые поддерживаются всеми реализациями. В документации на реализацию также могут быть описаны компромиссные решения и рекомендации относительно того, какие методы инициализации являются наиболее эффективными для данной конкретной реализации.

Разрушение мьютексов

Мьютекс можно разрушить сразу после разблокировки. Например, рассмотрим следующий код.

struct obj {

pthread_mutex_t om;

int refcnt;

};

obj_done (struct obj *op) {

pthread_mutex_lock (&op- >om);

if (—op- >refcnt == 0) {

pthread_mutex_unlock (&op- >om);

(A) pthread_mutex_destroy (&op- >om);

(B) free(op); } else

(С) pthread_mutex_unlock (&op->om);

}

В данном случае структура obj служит для учета количества ссылок, а функция obj_done вызывается всякий раз, когда удаляется ссылка на объект. Реализации должны позволить разрушение объекта и освобождение занимаемых им ресурсов (см. строки А и В) сразу после его разблокировки (строка С).

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

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

Смотри также

pthread_mutex_getprioceiling , pthread_mutex_lock , pthread_mutex_timedlock , pthread_mutexattr_getpshared , том Base Definitions стандарта IEEE Std 1003.1-2001, <pthread.h>.

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

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

Issue 6

Функции pthread_mutex_destroy и pthread_mutex_init от м ечены как часть опции Threads.

В целях согласования со стандарто м IEEE Std 1003.1d-1999 в раздел «С м отри также» была добавлена функция pthread_mutex_timedlock .

Раздел «Описание» б ы л отредактирован путе м при м енения интерпретации IEEE PASC Interpretation 1003.1с #34.

В целях согласования со стандартом ISO/IEC 9899: 1999 в прототип функции pthread_mutex_init было добавлено ключевое слово restrict.

pthread_mutex_getprioceiling, pthread_mutex_setprioceiling

Имя

THR TPP

pthread_mutex_getprioceiling, pthread_mutex_setprioceiling — функции считывания и установки предельного значения приоритета мьютекса (REALTIME THREADS).

Поделиться:
Популярные книги

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9