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

Тут можно читать онлайн Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - бесплатно полную версию книги (целиком) без сокращений. Жанр: 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. Вы узнаете о том, что такое потоковая модель памяти, и о том, какие средства поддержки многопоточности, в том числе запуска и синхронизации потоков, имеются в стандартной библиотеке. Попутно вы познакомитесь с различными нетривиальными проблемами программирования в условиях параллелизма.

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

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

Интервал:

Закладка:

Сделать

Но шаблон класса std::atomic<>— не просто набор специализаций. В нем есть основной шаблон, который можно использовать для создания атомарного варианта пользовательского типа. Поскольку это обобщенный шаблон класса, определены только операции load(), store()(а также присваивание значения пользовательского типа и преобразования в пользовательский тип), exchange(), compare_exchange_weak()и compare_exchange_strong().

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

• Операции сохранения , для которых можно задавать упорядочение memory_order_relaxed, memory_order_releaseи memory_оrder_sеq_cst.

• Операции загрузки , для которых можно задавать упорядочение memory_order_relaxed, memory_order_consume, memory_order_acquireи memory_order_seq_cst.

• Операции чтения-модификации-записи , для которых можно задавать упорядочение memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_relи memory_order_seq_cst.

По умолчанию для всех операций подразумевается упорядочение memory_оrder_sеq_cst.

Теперь рассмотрим, какие операции можно производить над каждым из стандартных атомарных типов, начиная с std::atomic_flag.

5.2.2. Операции над std::atomic_flag

Простейший стандартный атомарный тип std::atomic_flagпредставляет булевский флаг. Объекты этого типа могут находиться в одном из двух состояний: установлен или сброшен. Этот тип намеренно сделан максимально простым, рассчитанным только на применение в качестве строительного блока. Поэтому увидеть его в реальной программе можно лишь в очень специфических обстоятельствах. Тем не менее, он послужит нам отправной точкой для обсуждения других атомарных типов, потому что на его примере отчетливо видны общие относящиеся к ним стратегии.

Объект типа std::atomic_flag должен быть инициализирован значением ATOMIC_FLAG_INIT. При этом флаг оказывается в состоянии сброшен . Никакого выбора тут не предоставляется — флаг всегда должен начинать существование в сброшенном состоянии:

std::atomic_flag f = ATOMIC_FLAG_INIT;

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

После инициализации с флагом можно проделать только три вещи: уничтожить, очистить или установить, одновременно получив предыдущее значение. Им соответствуют деструктор, функция-член clear()и функция-член test_and_set(). Для обеих функций clear()и test_and_set()можно задать упорядочение памяти. clear() — операция сохранения , поэтому варианты упорядочения memory_order_acquireи memory_order_acq_relк ней неприменимы, a test_and_set()— операция чтения-модификации-записи, так что к ней применимы любые варианты упорядочения. Как и для любой атомарной операции, по умолчанию подразумевается упорядочение memory_order_seq_cst. Например:

f.clear(std::memory_order_release);← (1)

bool x = f.test_and_set(); ← (2)

Здесь при вызове clear() (1)явно запрашивается сброс флага с семантикой освобождения, а при вызове test_and_set() (2)подразумевается стандартное упорядочение для операции установки флага и получения прежнего значения.

Объект std::atomic_flagнельзя сконструировать копированием из другого объекта, не разрешается также присваивать один std::atomic_flagдругому. Это не особенность типа std::atomic_flag, а свойство, общее для всех атомарных типов. Любые операции над атомарным типом должны быть атомарными, а для присваивания и конструирования копированием нужны два объекта. Никакая операция над двумя разными объектами не может быть атомарной. В случае копирования и присваивания необходимо сначала прочитать значение первого объекта, а потом записать его во второй. Это две отдельные операции над двумя различными объектами, и их комбинация не может быть атомарной. Поэтому такие операции запрещены.

Такая ограниченность функциональности делает тип std::atomic_flagидеальным средством для реализации мьютексов-спинлоков. Первоначально флаг сброшен и мьютекс свободен. Чтобы захватить мьютекс, нужно в цикле вызывать функцию test_and_set(), пока она не вернет прежнее значение false, означающее, что теперь в этом потоке установлено значение флага true. Для освобождения мьютекса нужно просто сбросить флаг. Реализация приведена в листинге ниже.

Листинг 5.1.Реализация мьютекса-спинлока с использованием std::atomic_flag

class spinlock_mutex {

std::atomic_flag flag;

public:

spinlock_mutex():

flag(ATOMIC_FLAG_INIT) {}

void lock() {

while (flag.test_and_set(std::memory_order_acquire));

}

void unlock() {

flag.clear(std::memory_order_release);

}

};

Это очень примитивный мьютекс, но даже его достаточно для использования в сочетании с шаблоном std::lock_guard<>(см. главу 3). По своей природе, он активно ожидает в функции-члене lock(), поэтому не стоит использовать его, если предполагается хоть какая-то конкуренция, однако задачу взаимного исключения он решает. Когда дело дойдет до семантики упорядочения доступа к памяти, мы увидим, как гарантируется принудительное упорядочение, необходимое для захвата мьютекса. Пример будет приведён в разделе 5.3.6.

Тип std::atomic_flagнастолько ограничен, что его даже нельзя использовать в качестве обычного булевского флага, так как он не допускает проверки без изменения значения. На эту роль больше подходит тип std::atomic, который я рассмотрю ниже.

5.2.3. Операции над std::atomic

Из атомарных целочисленных типов простейшим является std::atomic. Как и следовало ожидать, его функциональность в качестве булевского флага богаче, чем у std::atomic_flag. Хотя копирующий конструктор и оператор присваивания по-прежнему не определены, но можно сконструировать объект из неатомарного bool, поэтому в начальном состоянии он может быть равен как true, так и false. Разрешено также присваивать объектам типа std::atomicзначения неатомарного типа bool:

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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