Главная » Просмотр файлов » А. Александреску - Современное проектирование на C++

А. Александреску - Современное проектирование на C++ (1119444), страница 40

Файл №1119444 А. Александреску - Современное проектирование на C++ (А. Александреску - Современное проектирование на C++) 40 страницаА. Александреску - Современное проектирование на C++ (1119444) страница 402019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 40)

Следует отметить, что реализация функции 5есьопцечтту довольно проста. Она создает конкретный объект класса ь(бестветгаскег, добавляет его в стек и регистрирует вызов функции асех1с. Приведенный ниже код очень важен для обобщения. Он вводит в рассмотрение функторы, предназначенные для уничтожения отслеживаемых объектов. Это позволяет не использовать оператор де1есе для удаления объекта из динамической памяти, поскольку может оказаться, что объект находится в альтернативной куче илн тле-то сше.

По умолчанию механизм уничтожения обьскта представляет собой указатель на функцию, вызывающую оператор де1есе. Эта функция называется Ое1есе, а ее шаблонный параметр задает тип удаляемого объекта. // вспомогательная функция для удаления объектов севр1асе <сурепаве т> эсгцсс Ое1есег эсастс чо1д ое1есе(т+ рОЬ)) ( де1ете РОЬ)! ) О конкретный обьект класса ст'Еестветгаскег для объектов типа т севр1асе <сурепаве т, сурепаве Оеэсгоуег> с1аьэ сопсгесестрес)ветгас!сег : рцЬ)тс ь!Еесзветгас!сег ' Фактически функция бесьопдечтсу использует толька функцию эсд::геа11ос, заменяющую собой н функцию ва11ос, н функцию тгее. Если вызвать се с нулевым уквзатслсч, она велст себя как функция эсд::ва11ос, в если завять нулевой рвзмср, онэ имитирует работу функции эсд::тгее.

165 Глава 6, Реализация шаблона 8!пц!етоп рцЬ11с: сопсгетеь1Еет1иетгас1ег(т* р, цпэ1доед 1пт 1оядеч1ту, реэтгоуег д) :ь1тет1иетгасйег(1опдеч1су), ртгаскед (р), деэтгоуег (д) () -сопсгетеь1тет1иетгас1егО деэтгоуег (ртгас)сед ); рг1чате: т* ртгасйед ; пеэтгоуег деэтгоуег; чо1д лтях1тяпО; // необходимое объявление теир1ате <турепаие т, турепаве оеэтгоуег> чо1д эетьопдеч1ту(т* рпупоЬ)ест, 1пэ1дпед 1пт 1опдеч1ту, пеэтгоуег д = яг1чате::пе1есег<т>::ое1ете) тгас)сеглггау рнеилггау = этатзс саэт<тгасйеглггау>( этд::геа11ос(ртгаскеглггау, е1еиептэ + 1)); 1т (1рнеилггау) тЬгои этд::Ьад а11ос0; ь11ет1иетгас~ег* р = пеи сопсгесеь1Фетзиетгас1ег <т, пеэтгоуег>(рпупоЬ)ест, 1опдеч1ту, д); ртгасКеглггау = рнеилггау; тгас)сеглггау роэ = этд::иррег Ьоцпд( ртгасйеглггау, ртгасКеглггау + е1еиептэ, 1опдечдсу, Соираге); этд::сору Ьас)сиагд(роэ, ртгас1еглггау + е1еиептэ, ртгас)сегаггау + е1еиепгэ + 1); *роз = р; ++е1еиептэ; этд::атехдт(лтвх)тяп); Использование функций этд::цррег Ьоипд и эгд::сору Ьас)сиагд намного облегчает чтение и понимание этого нетривиального кода.

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

Объекты с одинаковой продолжительностью жизни следуют в соответствии с очередностью их вставки. функция лтях1тгп выталкивает объект с наименьшей продолжительностью жизни (т,е. последний элемент массива) и удаляет его. Удаление указателя на объект класса ь11ет1иетгас)сег приводит к вызову деструктора класса сопсгетеь1тет1иетгас)сег, который в свою очередь удаляет объект. этатдс чо1д атях1тяпО аьвегт(е1еиепгэ > О $$ ртгасйеглггау != О); // выбираем элемент, находящийся на вершине стека ь1тет1иетгасМег* ртор = ртгасйеглггау[е1еиептэ — Ц; 166 Часть И.

Компоненты // удаляем этот объект из стека. // ошибки не проверяются -- функция геа11ос, // примененная к меньшему размеру памяти, // всегда работает правильно ртгаскегдггау = (тгаскегдггау*)згд::геа11ос(ртгаскегдггау, — е1еюепгз); // Уничтожаем элемент де1еге ртор; Созлавая функцию агах)геп, следует быть внимательным. Она должна выталки- вать из стека элемент, находяшийся на вершине, и удалять его. В свою очередь дест- руктор удаляемого элемента ликвидирует управляемый им объект. Проблема заключа- ется в том, что функция дгвх1гЕп должна вытолкнуть объект из вершины стека до его удаления, поскольку разрушение одного объекта может повлечь за собой создание другого, который будет затолкнут обратно в стек.

Несмотря на то что это выглядит до- вольно необычно, именно так развиваются события, когда деструктор класса кеу- Ьоагд пытается использовать объект класса год. По умолчанию код скрывает структуры данных, и функция дгдх)геп находится в пространстве имен ег)чаге. Пользователи могут любоваться лишь вершиной айсбер- га — функцией 5егсопдеч1гу. Синглтоны с заданной продолжительностью жизни могут использовать функцию 5еггопдеч1гу следуюшим образом. с1аьз сод риЬ1)с: згаг1с чо1д сгеагеО ( // создаем экземпляр ртпзгапсе = пеи сод; // эти строки добавлены 5егсопдеч\гу(*гЬ15, 1опдеч)гу ); ) // Остальная часть реализации пропущена. // еункция год::тпзгапсе определяется, как и прежде.

рг1чаге: // определяем фиксированную продолжительность жизни ьгаг)с сопьг мпз)диет )пг 1опдеч1гу = 2; эгаг)с сод* ртпзгапсе ; ); Если реализовать классы кеуЬоагб и о1зр1ау, следуя описанному выше подходу, но задать продолжительность жизни их объектов равной 1, то объект класса год их обязательно переживет. Решает ли это проблему К1)Е? Что если приложение использует несколько потоков? 6.9. Продолжительность жизни обьектов в многопоточной среде Синглтоны должны работать и с потоками тоже.

Допустим, наше приложение только что начало работу, и два потока имеют доступ к привеленному ниже синглтону. 51пд1егопй 5)пд1егоп::тпвгапсеО ( 1Ф(!ртпэгапсе) // 1 1Б7 Глава б. Реализация шаблона 31пц!егоп с р1ПЗГапсе = пев 5)пц1егоп; // 2 гесигп *р1пзтапсе ; // 3 ) Первый поток входит в функцию 1озтаосе и проверяет условие оператора 11. Поскольку поток входит в функцию впервые, значение переменной ртпзтапсе равно О. В таком случае поток управления достигает строки с комментарием //2 и готовится вызвать оператор пею, Планировшик заданий операционной системы может прервать первый поток в этой точке и передать управление другому потоку. Второй поток вызывает функцию 5)пц1етоп::1пзтапсе() и обнаруживает, что значение переменной р1пзтаосе также равно нулю, поскольку первый поток ее еше не менял, До сих пор первый поток только проверял значение переменной р1пзтапсе .

Теперь второй поток вызывает оператор пею, присваивает переменной р1пзтапсе некий адрес и покидает функцию. К несчастью. первый поток снова приходит в сознание, вспоминает, что осталось выполнить лишь строку с комментарием //2, изменяет значение переменной р1пзтапсе и выхолит из функции. Когда пыль рассеивается, оказывается, что вместо олного обьекта класса 5зпц)егоп созданы лва, причем один из них очевидно лишний. В каждом потоке хранится по одному обьекгу класса 51пц)етоп, и приложение погружается в хаос.

И это только пана из возможных ситуаций! А что будет, если к синглтону имеют лоступ несколько потокову (Представьте себе процесс отладки такой программы!) Опытные программисты, разрабатываюшие многопоточные приложения, узнают здесь классическое состязание (гасе з!шайоп), Следует быть готовым к тому, что шаблон проектирования 51пц1етоп столкнется с потоками. Синглтон относится к глобальным ресурсам совместного использования и должен участвовать в состязании с другими объектами, решая проблемы нескольких потоков.

б.й. 1. Шаблон блокировки с двойной лроваркой Всестороннее обсуждение многопоточных синглтонов впервые было проведено Дугласом Шмидтом (Ооой)аз Бслглк)г, 1996). В этой же статье было описано очень остроумное решение, названное шаблоном цоиЫе-Сбескеб ьос!слпц (блокировка с двойной проверкой), предложенное Дугласом Шмидтом и Тимом Харрисоном (Тпп НапЬоп). Очевилное решение сушествует, но выглядит непривлекательно. 5з'пц)егопб 5зпц)есоп::1пзгапсеО // юитех — объект мьютекса. // мьютексом управляет обьехт класса ьоск ьоск циагг((юитех ); )Г (!р1пзтапсе ) р1пзтапсе = пеа 51пц1етоп; гетигп *р1пзгапсе Класс ьоск -- это классический обработчик мьютексов (детали описаны в приложении).

Конструктор класса ьосх захватывает мьютекс, а деструктор освобождает его. Пока мьютекс витек захвачен, другие потоки, пытаюшиеся завладеть им, ожмлают своей очерели. Часть !!. Компоненты 168 Это освобождает нас от состязания: пока поток присвоен объекту р1пзтапсе, остальные останавливаются в конструкторе даат. Когда другой поток пытается захватить блокировку, он обнаруживает уже проинициализированную переменную ртпзтапсе, и все проходит гладко.

Однако правильное решение не всегда оказывается приемлемым. Неудобство заключается в недостатке эффективности. Каждый вызов функции-члена 1пзталсе влечет за собой блокировку и освобождение объекта синхронизации, хотя состязание за ресурсы возникает, образно говоря, один раз в жизни. Эти операции обычно очень затратны. Их стоимость намного превышает стоимость выполнения простой проверки з Т(! Р1пзтапсе), (В современных системах время, затрачиваемое на проверку и ветвление, обычно отличается от времени, уходяшего на блокировку критических разделов, на несколько порядков.) Для того чтобы избежать дополнительных затрат, можно было бы предложить следующее решение. 5з пд)еголин 5з од)етоп:: 1пзтапсе() ( зТ (!р1пзтапсе ) ( ьоск дцаго(витек ); р1пзтапсе = пеи 5зпд)етоп; гетцгп *р1пзтапсе ; Теперь дополнительных затрат нет, однако осгалось состязание за ресурсы.

Первый поток проходит проверку 1Ф, однако прямо перед входом в синхронизированную часть кода планировщик заданий операционной системы прерывает его и передает управление другому потоку. Второй поток также проходит проверку 11 (и, естественно, обнаруживает нулевой указатель), входит в синхронизированную часть кода и выполняет ее.

Характеристики

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6486
Авторов
на СтудИзбе
303
Средний доход
с одного платного файла
Обучение Подробнее