Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Эффективное использование STL. Библиотека программиста - Мейерс С.

Мейерс С. Эффективное использование STL. Библиотека программиста — Спб.: Питер , 2002. — 224 c.
ISBN 5-94723-382-7
Скачать (прямая ссылка): effektivnoeispolzovaniestlbibliote2002.djvu
Предыдущая << 1 .. 27 28 29 30 31 32 < 33 > 34 35 36 37 38 39 .. 114 >> Следующая

строки, a f i nd тоже возвращает управление в конце строки.
Чтобы этот фрагмент был потоково-безопасным, блокировка v должна
сохраняться от строки 1 до строки 3. Трудно представить, каким образом
реализация STL могла бы автоматически придти к такому выводу. А если
учесть, что использование примитивов синхронизации (семафоров, мьютексов1
и т. д.) обычно сопряжено с относительно высокими затратами, еще труднее
представить, каким образом реализация могла бы сделать это без
значительного снижения быстродействия по сравнению с программами, которым
априорно известно, что в строках 1-3 с v будет работать только один
программный поток.
Понятно, почему в решении проблем многопоточности не стоит полагаться на
реализацию STL. Вместо этого в подобных случаях следует самостоятельно
синхронизировать доступ. В приведенном примере это может выглядеть так:
vector<int> v:
getMutexFor(v);
vector<i nt>::i terator fi rst5( fi nd(v.begi n(),v.end(), 5));
if (firsts !" v.endO) { // Теперь эта строка безопасна
*first5 = 0; // И эта строка тоже
}
releaseMutexFor(v);
В другом, объектно-ориентированном, решении создается класс Lock, который
захватывает мьютекс в конструкторе и освобождает его в деструкторе, что
сводит к минимуму вероятность вызова getMutexFor без парного вызова
releaseMutexFor. Основа такого класса (точнее, шаблона) выглядит примерно
так:
tempiate<typename Container> // Базовый шаблон для классов.
class Lock{ // захватывающих и освобождающих мьютексы
public: // для контейнеров: многие технические
// детали опущены Lock(const Containers container)
:с(container)
{
getMutexFor(с); // Захват мьютекса в конструкторе
}
-Lock ()
{
releaseMutexFor(c): // Освобождение мьютекса в деструкторе
}
private:
const Containers с:
}:
1 В среде программистов данный термин (англ. mutex) встречается также в
варианте "мутекс". - Примеч. ред.
Совет 12 65
Концепция управления жизненным циклом ресурсов (в данном случае -
мьютексов) при помощи специализированных классов вроде Lock
рассматривается в любом серьезном учебнике C++. Попробуйте начать с книги
Страуструпа (Stroustrup) "The C++ Programming Language" [7], поскольку
именно Страуструп популяризировал эту идиому, однако информацию также
можно найти в совете 9 "More Effective C++". Каким бы источником вы ни
воспользовались, помните, что приведенный выше класс Lock урезан до
абсолютного минимума. Полноценная версия содержала бы многочисленные
дополнения, не имеющие никакого отношения к STL. Впрочем, несмотря на
минимализм, приведенная версия Lock вполне может использоваться в
рассматриваемом примере:
vector<int> v:
{ II Создание нового блока
Lock<vector<int> > lock(v): II Получение мьютекса
vector<int>::iterator first5(find(v.begin().v.end().5)): if (first5 !-
v.endO) {
*first5 - 0:
}
} II Закрытие блока с автоматическим
II освобождением мьютекса
Поскольку мьютекс контейнера освобождается в деструкторе Lock, важно
обеспечить уничтожение Lock сразу же после освобождения мьютекса. Для
этого мы создаем новый блок, в котором определяется объект Lock, и
закрываем его, как только надобность в мьютексе отпадает. На первый
взгляд кажется, что вызов releaseMutexFor попросту заменен необходимостью
закрыть блок, но это не совсем так. Если мы забудем создать новый блок
для Lock, мьютекс все равно будет освобожден, но это может произойти
позднее положенного момента - при выходе из внешнего блока. Если забыть о
вызове releaseMutexFor, мьютекс вообще не освобождается.
Более того, решение, основанное на классе Lock, лучше защищено от
исключений. C++ гарантирует уничтожение локальных объектов при
возникновении исключения, поэтому Lock освободит мьютекс, даже если
исключение произойдет при использовании объекта Lock. При использовании
парных вызовов getMutexFor/ releaseMutexFor мьютекс не будет освобожден,
если исключение происходит после вызова getMutexFor, но перед вызовом rel
easeMutexFor.
Исключения и управление ресурсами важны, но данный совет посвящен другой
теме - потоковой безопасности в STL. Как говорилось выше, вы можете
надеяться на то, что реализация библиотеки обеспечивает параллельное
чтение из одного контейнера и одновременную запись в разные контейнеры.
Не надейтесь, что библиотека избавит вас от ручной синхронизации и не
рассчитывайте на поддержку многопоточности.
Контейнеры vector и string
Все контейнеры STL по-своему полезны, однако большинство программистов
C++ работает с vector и stri ng чаще, чем с их собратьями, и это вполне
понятно. Ведь контейнеры vector и stri ng разрабатывались как замена
массивов, а массивы настолько полезны и удобны, что встречаются во всех
коммерческих языках программирования от COBOL до Java.
В этой главе контейнеры vector и string рассматриваются с нескольких
точек зрения. Сначала мы разберемся, чем они превосходят классические
массивы STL, затем рассмотрим пути повышения быстродействия vector и
string, познакомимся с различными вариантами реализации string, изучим
Предыдущая << 1 .. 27 28 29 30 31 32 < 33 > 34 35 36 37 38 39 .. 114 >> Следующая