Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ

Тут можно читать онлайн Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство ДМК Пресс, год 2012. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
  • Автор:
  • Жанр:
  • Издательство:
    ДМК Пресс
  • Год:
    2012
  • Город:
    Москва
  • ISBN:
    978-5-94074-448-1
  • Рейтинг:
    5/5. Голосов: 11
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 100
    • 1
    • 2
    • 3
    • 4
    • 5

Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ краткое содержание

Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - описание и краткое содержание, автор Энтони Уильямс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru
В наши дни компьютеры с несколькими многоядерными процессорами стали нормой. Стандарт С++11 языка С++ предоставляет развитую поддержку многопоточности в приложениях. Поэтому, чтобы сохранять конкурентоспособность, вы должны овладеть принципами и приемами их разработки, а также новыми средствами языка, относящимися к параллелизму.
Книга «Параллельное программирование на С++ в действии» не предполагает предварительных знаний в этой области. Вдумчиво читая ее, вы научитесь писать надежные и элегантные многопоточные программы на С++11. Вы узнаете о том, что такое потоковая модель памяти, и о том, какие средства поддержки многопоточности, в том числе запуска и синхронизации потоков, имеются в стандартной библиотеке. Попутно вы познакомитесь с различными нетривиальными проблемами программирования в условиях параллелизма.

Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - читать онлайн бесплатно полную версию (весь текст целиком)

Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - читать книгу онлайн бесплатно, автор Энтони Уильямс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
Рис 51Разбиение structна объекты и ячейки памяти Вопервых вся структура - фото 9

Рис. 5.1.Разбиение structна объекты и ячейки памяти

Во-первых, вся структура — это один объект, который состоит из нескольких подобъектом, по одному для каждого члена данных. Битовые поля bf1и bf2занимают одну ячейку памяти, объект sтипа std::stringзанимает несколько ячеек памяти, а для каждого из остальных членов отведена своя ячейка. Обратите внимание, что битовое поле нулевой длины bf3заставляет отвести для bf4отдельную ячейку.

Отсюда можно сделать несколько важных выводов:

• каждая переменная — объект, в том числе и переменные, являющиеся членами других объектов;

• каждый объект занимает по меньшей мере одну ячейку памяти;

• переменные фундаментальных типов, например intили char, занимают в точности одну ячейку памяти вне зависимости от размера, даже если являются соседними или элементами массива;

• соседние битовые поля размещаются в одной ячейке памяти.

Уверен, что вы недоумеваете, какое отношение всё это имеет к параллелизму. Давайте разберемся.

5.1.2. Объекты, ячейки памяти и параллелизм

Для многопоточных приложений на С++ понятие ячейки памяти критически важно. Если два потока обращаются к разным ячейкам памяти, то никаких проблем не возникает и всё работает, как надо. Но если потоки обращаются к одной и той же ячейке, то необходима осторожность. Если ни один поток не обновляет ячейку памяти, то всё хорошо — доступ к данным для чтения не нуждается ни в защите, ни в синхронизации. Если же какой-то поток модифицирует данные, то возможно состояние гонки, описанное в главе 3.

Чтобы избежать гонки, необходимо принудительно упорядочить обращения из двух потоков. Один из возможных способов такого упорядочения дают мьютексы (см. главу 3) — если захватывать один и тот же мьютекс перед каждым обращением, то одновременно получить доступ к ячейке памяти сможет только один поток, так что упорядочение налицо. Другой способ упорядочить доступ из двух потоков — воспользоваться свойствами синхронизации, присущими атомарным операциям (о том, что это такое, см. раздел 5.2) над теми же или другими ячейками памяти. Такое использование атомарных операций описано в разделе 5.3. Если к одной и той же ячейке обращаются более двух потоков, то упорядочение должно быть определено для каждой пары.

Если два обращения к одной и той же ячейке памяти из разных потоков не упорядочены и одно или оба обращения не являются атомарными и одно или оба обращения являются операциями записи, то имеет место гонка за данными, что приводит к неопределенному поведению.

Эта фраза критически важна: неопределенное поведение — один из самых грязных закоулков С++. Согласно стандарту языка, любое неопределенное поведение отменяет всякие гарантии — поведение всего приложения становится неопределённым, и оно может делать все, что угодно. Я знаю один пример неопределённого поведения, в результате которого загорелся монитор. Хотя маловероятно, что такое приключится с вами, гонка за данными безусловно является серьезной ошибкой, которой следует всеми силами избегать.

В этой фразе есть и еще один важный момент: избежать неопределенного поведения поможет использование атомарных операций для доступа к ячейке памяти, за которую возможна гонка. Саму гонку это не предотвращает — какая именно атомарная операция первой получит доступ к ячейке памяти, все равно не определено, — но программа тем не менее возвращается в область определённого поведения.

Прежде чем мы перейдем к атомарным операциям, нужно разобраться еще в одной важной концепции, касающейся объектов и ячеек памяти: порядке модификации.

5.1.3. Порядок модификации

Для каждого объекта в программе на С++ определён порядок модификации, состоящий из всех операций записи в объект из всех потоков программы, начиная с инициализации объекта. В большинстве случаев порядок меняется от запуска к запуску, но при любом выполнении программы все имеющиеся в системе потоки должны договориться о порядке модификации. Если объект не принадлежит одному из описанных в разделе 5.2 атомарных типов, то вы сами отвечаете за обеспечение синхронизации, достаточной для того, чтобы потоки могли договориться о порядке модификации каждой переменной. Если разные потоки видят разные последовательности значений одной и той же переменной, то имеет место гонка за данными и, как следствие, неопределённое поведение (см. раздел 5.1.2). Если вы используете атомарные операции, то за обеспечение необходимой синхронизации отвечает компилятор.

Это требование означает, что некоторые виды спекулятивного исполнения [11] О том, что такое спекулятивное исполнение, см. http://en.wikipedia.org/wiki/Speculative_execution. Прим. перев. не разрешены, потому что после того как некоторый поток увидел определённое значение объекта при данном порядке модификации, последующие операции чтения в том же потоке должны возвращать более поздние значения, а последующие операции записи в тот же объект в этом потоке должны происходить позже при данном порядке модификации. Кроме того, операция чтения объекта, следующая за операцией записи в этот объект, должна вернуть либо записанное значение, либо другое значение, которое было записано позже при данном порядке модификации этого объекта. Хотя все потоки обязаны договориться о порядке модификации каждого объекта в программе, не требуется, чтобы они договаривались об относительном порядке операций над разными объектами. Дополнительные сведения об упорядочении операций, выполняемых в разных потоках, см. в разделе 5.3.3.

Итак, что понимается под атомарной операцией и как ими можно воспользоваться для принудительного упорядочения?

5.2. Атомарные операции и типы в С++

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

И наоборот, если операция не атомарная, то другой поток может видеть, что она выполнена частично. Если это операция сохранения, то значение, наблюдаемое другим потоком, может не совпадать ни со значением до начала сохранения, ни с сохраненным значением. С другой стороны, операция загрузки может извлечь часть объекта, после чего значение будет модифицировано другим потоком, а затем операция прочитает оставшуюся часть объекта. В результате будет извлечено значение, которое объект не имел ни до, ни после модификации. Это простая проблематичная гонка, описанная в главе 3, но на этом уровне она может представлять собой гонку за данными (см. раздел 5.1) и, стало быть, являться причиной неопределённого поведения.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Энтони Уильямс читать все книги автора по порядку

Энтони Уильямс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Параллельное программирование на С++ в действии. Практика разработки многопоточных программ отзывы


Отзывы читателей о книге Параллельное программирование на С++ в действии. Практика разработки многопоточных программ, автор: Энтони Уильямс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x