Главная » Просмотр файлов » С. Мейерс - Эффективный и современный C++

С. Мейерс - Эффективный и современный C++ (1114942), страница 63

Файл №1114942 С. Мейерс - Эффективный и современный C++ (С. Мейерс - Эффективный и современный C++) 63 страницаС. Мейерс - Эффективный и современный C++ (1114942) страница 632019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Это необходи­мо, поскольку применение j o i n или detach к неподключаемому объекту приводитк неопределенному поведению. Может быть так, что клиент создает std : : th read,затем создает из неrо объект ThreadRAI I , использует функцию-член get для полу­чения доступа к t, а затем выполняет перемещение из t или вызывает для него j o inили detach. Каждое из этих действий делает t неподключаемым.if ( t . joinaЬle ( ) ) {if (action == DtorAction : : join)t . j oin ( ) ;else {t . deta.ch о ;Если в приведенном фрагменте вас беспокоит возможность условия гонки из-за того,что между вызовами t .

j oi naЫe { ) и j oi n или detach другой поток может сделатьt неподключаемым, то ваша интуиция заслуживает похвалы, но ваши опасенияв данном случае беспочвенны. Объект std : : thread может изменить состояниес подключаемого на неподключаемое только путем вызова функции-члена, напримерj oin, detach или операции перемещения. В момент вызова деструктора ThreadRAI Iникакие другие потоки не должны вызывать функцию-член для этого объекта.

При2 58Гnа ва 7 . Параnnеnьные вычисnениянаnичии одновременных вызовов, определенно, имеется условие rонки, но не внутридеструктора, а в клиентском коде, который пытается вызвать одновременно двефункции-члена объекта (деструктор и что-то еще). В общем случае одновременныевызовы функций-членов для одного объекта безопасны, только если все ониявляются константными функциями-членами (см. раздел 3.

1 0).Использование ThreadRAI I в нашей функции doWor k может выглядеть следующимобразом:bool doWor k ( s td : : function<bool ( int ) > filter, // Как и ранееint maxVal = tenМi l l ion)std : : vector<int> goodVa l s ;11 Как и ранееТhreadRAII t ( // u s e RAI I obj ectstd : : thread ( [ & fi lter, maxVal , &goodVa l s ]{for ( auto i = О ; i <= maxVal ; ++ i ){ i f ( filter ( i ) ) goodVal s .

push_back ( i ) ;}) 'ТhreadRAII : : DtorAction : : join1 1 Действие RAI I);auto nh = t . get ( ) . native_handle ( ) ;if( condi t i onsAreSa t is fi ed () )t . get () . j oin ( ){;performCompu ta t ion (goodVa l s ) ;return true ;return fa l s e ;В этом случае мы выбрали использование j o in для асинхронно выполняющегося пото­ка в деструкторе ThreadRAI I, поскольку, как мы видели ранее, применение detach можетпривести к настоящим кошмарам при отладке.

Мы также видели ранее, что применениеj oin может вести к аномалиям производительности (что, откровенно говоря, также мо­жет быть неприятно при отладке), но выбор между неопределенным поведением (к кото­рому ведет detach), завершением программы (при использовании обычного std : : thread)и аномалиями производительности предопределен - мы выбираем меньшее из зол.Увы, раздел 7.5 демонстрирует, что применение ThreadRAI I для выполнения j o i n приуничтожении std : : t hread иногда может привести не к аномалии производительности, а кполному "зависанию" программы.

"Правильным" решением этого типа проблем было бы со­общить асинхронно выполняющемуся лямбда-выражению, что в ero услугах мы больше ненуждаемся и оно должно поскорее завершиться. Увы, С++ 1 1 не поддерживает прерь1ваемыепотоки. Их можно реализовать вручную, но данный вопрос выходит за рамки нашей книги4.4Вы можете обратиться к книге Энтони Вильямса (Anthony Wil\iams) С++ Concurrency in Action(Manning Puhlications, 20 1 2), раздел 9.2.7.3.Деnайте std::thread неподкnючаемым на всех путях выпоnнения259В разделе 3. 1 1 поясняется, что, поскольку T h r eadRAI I объявляет деструктор, в немнет генерируемых компилятором перемещающих операций, но причин, по которымThreadRA I I не должен быть перемещаемым, тоже нет.

Если бы компилятор генерировалтакие функции, то они демонстрировали бы верное поведение, так что просто попросимкомпилятор их все же сгенерировать:class ThreadRAI I {puЫ ic :enum class DtorActionj oin, detach ) ;ThreadRAI I ( st d : : thread&& t , DtorAct ion а ): action ( а ) , t ( st d : : move ( t ) ) { )11 Как и ранее11 Как и ранее-ThreadRAI I ( ){11 Как и ранее/ / ПоддержкаТhreadRAII (ТhreadRAII&&) =clefault;ТhreadRAII& operator= (ТhreadRAII&&) =clefault ; // перемещенияstd : : thread& get ( ) { return t ; )1 1 Как и ранее11 Как и ранееprivate :DtorActioп action;std : : thread t ;);Следует запомнить•Делайте s t d : : t hread неподключаемыми на всех путях выполнения.•Применение j oi n при уничтожении объекта может привести к трудно отлаживае­мым аномалиям производительности.•Применение d e t a ch при уничтожении объекта может привести к трудно отлажива­емому неопределенному поведению.•Объявляйте объекты s t d : : t h re a d в списке членов-данных последними.7 .4.

П омните о разном поведениидеструкторов дескрип торов потоковВ разделе 7.3 вы узнали, что подключаемый s t d : : thread соответствует базовому си­стемному потоку выполнения. Фьючерс для неотложенной задачи (см. раздел 7.2) имеетсхожую связь с системным потоком. А раз так, и объекты s t d : : t hread, и объекты фью­черсов можно рассматривать как дескрипторы (handles) системных потоков.260Глава 7 . Па раллельные вычисленияС этой точки зрения интересно, что std : : thread и фьючерсы совершенно по-разномуведут себя в деструкторах.

Как упоминалось в разделе 7.3, уничтожение подключаемогоs t d : : t hread завершает работу программы, поскольку две очевидные альтернативы неявный вызов j o i n и неявный вызов detachоказываются еще более плохим выбо­ром. Однако деструктор фьючерса ведет себя так, как если бы и ногда выполнялся не­явный вызов j oin, иногда - неявный вызов detach, а иногда - ни то и ни другое. Онникогда не приводит к завершению работы программы. Поведение этого дескрипторапотока заслуживает более внимательного рассмотрения.Начнем с наблюдения, что фьючерс представляет собой один из концов канала связи,по которому вызываемая функция передает результаты вызывающей5• Вызываемая функция(обычно работающая асинхронно) записывает результат вычислений в коммуникационныйканал (обычно с помощью объекта std : : promise), а вызывающая функция читает результатс помощью фьючерса.

Вы можете представлять это для себя следующим образом (пунктир­ные стрелки показывают поток информации от вызываемой функции к вызывающей):-std : : promis e Вызываемая 1Выз ывающая . фьючерсФункция- - - - --- - - - --- - - --- - - --- -!обi.�но) функцияНо где же хранится результат вызываемой функции? Вызываемая функция может за­вершиться до того, как будет вызвана функция-член get соответствующего фьючерса, такчто результат не может быть сохранен в std : : promi se вызываемой функции. Этот объект,будучи локальным по отношению к вызываемой функции, уничтожается по ее завершении.Результат не может храниться и во фьючерсе вызывающей функции, поскольку(среди прочих причин) s td : : future может быть использован для создания объектаs t d : : sha red future (тем самым передавая владение результатом вызываемой функцииот s t d : : future в std : : sha red_future), который затем, после уничтожения исходногоs t d : : fut ure, может быть многократно копирован.

С учетом того, что не все типы ре­зультата могут быть скопированы (например, существуют только перемещаемые типы)и что результат должен существовать до тех пор, пока как минимум последний фьючерсна него ссылается, какой из потенциально многих фьючерсов, соответствующих вызыва­емой функции, должен содержать ее результат?Поскольку ни объекты, связанные с вызываемой функцией, н и объекты, связанныес вызывающей функцией, не являются подходящими местами для хранения результатавызываемой функции, они должны храниться где-то вне этих объектов.

Такое местопо­ложение известно как общее состояние (shared state). Это общее состояние обычно пред­ставлено объектом в динамической памяти, но его тип, интерфейс и реализация в стан­дарте языка не указаны. Авторы стандартной библиотеки могут реализовывать общиеСОСТОЯНИЯ так, как хотят.5 В разделе7.5 поясняется, что разновидность канапа связи фьючерса может быть использованаи для других целей. Однако в этом разделе мы будем рассматривать только его применение в ка­честве механизма дпя передачи резупьтата из вызываемой функции вызывающей.7.4. Помните о разном поведении деструкторов дескрипторов потоков261Мы можем представить себе отношения между вызываемой функцией, вызывающейфункцией и общим состоянием следующим образом (пунктирными стрелками вновьпредставлен поток информации):Общее состояниесВызывающая · Ф�'О.11!!!.. _ _ _ _ _ _ Результат , _ _s_to.:.

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

Тип файла
PDF-файл
Размер
12,67 Mb
Тип материала
Высшее учебное заведение

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

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