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

Здесь есть возможность читать онлайн «Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Москва, Год выпуска: 2012, ISBN: 2012, Издательство: ДМК Пресс, Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

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

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

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

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

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

next.external_count = 0;

}

};

public:

void push(T new_value) {

std::unique_ptr new_data(new T(new_value));

counted_node_ptr new_next;

new_next.ptr = new node;

new_next.external_count = 1;

counted_node_ptr old_tail = tail.load();

for (;;) {

increase_external_count(tail, old_tail); ← (5)

T* old_data = nullptr;

if (old_tail.ptr->data.compare_exchange_strong(← (6)

old_data, new_data.get())) {

old_tail.ptr->next = new_next;

old_tail = tail.exchange(new_next);

free_external_counter(old_tail); ← (7)

new_data.release();

break;

}

old_tail.ptr->release_ref();

}

}

};

В листинге 7.15 tailтеперь имеет такой же тип atomic, как и head (1), а в структуру nodeдобавлен член countвместо прежнего internal_count (3). Член countсам представляет собой структуру с двумя полями: internal_countи external_counters (2). Под поле external_countersотведено только 2 бита, потому что внешних счетчиков может быть не более двух. Воспользовавшись битовыми полями и отведя под internal_count30 бит, мы ограничили длину поля счетчика 32 битами. В результате мы убиваем сразу двух зайцев: и значение внутреннего счетчика может быть достаточно велико, и вся структура помещается в машинное слово на 32- и 64-разрядных машинах. Очень важно изменять счетчики как единое целое, чтобы избежать гонки. Как это делается, мы покажем чуть ниже. На многих платформах хранение структуры в одном машинном слове повышает шансы на то, что атомарные операции окажутся свободными от блокировок.

При инициализации структуры nodeв поле internal_countзаписывается 0, а в поле external_counters— 2 (4), потому что сразу после добавления нового узла в очередь на него есть две ссылки: из tailи из указателя nextв предыдущем узле. Код самой функции push()похож на приведенный в листинге 7.14 с тем отличием, что перед тем как разыменовывать загруженное из tailзначение, чтобы вызвать compare_exchange_strong()для члена узла data (6), мы вызываем новую функцию increase_external_count()которая увеличивает счетчик (5), а затем функцию free_external_counter()для старого хвоста old_tail (7).

Разобравшись с push(), обратим наши взоры на pop(). В ее коде (см. листинг 7.16) логика подсчета ссылок из реализации pop()в листинге 7.11 комбинируется с логикой извлечения из очереди в листинге 7.13.

Листинг 7.16.Извлечение узла из очереди без блокировок с подсчётом ссылок на tail

template

class lock_free_queue {

private:

struct node {

void release_ref();

};

public:

std::unique_ptr pop() {

counted_node_ptr old_head =

head.load(std::memory_order_relaxed); ← (1)

for (;;) {

increase_external_count(head, old_head);← (2)

node* const ptr = old_head.ptr;

if (ptr == tail.load().ptr) {

ptr->release_ref();← (3)

return std::unique_ptr();

}

if (head.compare_exchange_strong(old_head, ptr->next)) {← (4)

T* const res = ptr->data.exchange(nullptr);

free_external_counter(old_head);← (5)

return std::unique_ptr(res);

}

ptr->release_ref();

}

}

};

Все начинается с загрузки значения old_headперед входом в цикл (1)и до увеличения внешнего счетчика в загруженном значении (2). Если узел headсовпадает с tail, то можно освободить ссылку (3)и вернуть нулевой указатель, потому что очередь пуста. Если же в очереди есть данные, то мы пытаемся заявить на них свои права с помощью compare_exchange_strong()(4). Как и в случае стека в листинге 7.11, мы при этом сравниваем внешний счетчик и указатель как единое целое; если хотя бы один из них изменился, то мы должны вернуться в начало цикла, освободив предварительно ссылку 6. Если обмен завершился удачно, то мы получили в свое распоряжение данные в узле, поэтому можем вернуть их вызывающей программе, освободив предварительно внешний счетчик ссылок на извлеченный узел (5). После того как оба внешних счетчика освобождены, а внутренний счетчик обратился в нуль, сам узел можно удалять. Вспомогательные функции подсчета ссылок приведены в листингах 7.17, 7.18 и 7.19.

Листинг 7.17.Освобождение ссылки на узел в очереди без блокировок

template

class lock_free_queue {

private:

struct node {

void release_ref() {

node_counter old_counter =

count.load(std::memory_order_relaxed);

node_counter new_counter;

do {

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

Интервал:

Закладка:

Сделать

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

Представляем Вашему вниманию похожие книги на «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


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

Обсуждение, отзывы о книге «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x