Читаем Параллельное программирование на С++ в действии полностью

Новый стандарт С++ отнюдь не исчерпывается поддержкой параллелизма; в нем появилось немало других языковых средств и новых библиотек. В этом приложении я вкратце расскажу о тех новых возможностях, которые используются в библиотеке многопоточности и встречаются в этой книге. За исключением модификатора thread_local (рассматриваемого в разделе А.8), все они не имеют прямого отношения к параллелизму, однако важны и (или) полезны для написания многопоточного кода. Я ограничился лишь теми конструкциями, которые либо необходимы (например, ссылки на r-значения), либо делают код проще и яснее. Поначалу разобраться в программе, где применяются эти конструкции, будет трудно, но, познакомившись с ними поближе, вы согласитесь, что, вообще говоря, включающий их код проще, а не сложнее для понимания. По мере распространения С++11 описываемые средства будут встречаться в программах все чаще.

А теперь, без дальнейших предисловий, начнем с изучения ссылок на r-значения — средства, которое широко используется в библиотеке Thread Library для передачи владения (потоками, блокировками и вообще всем на свете) от одного объекта другому.

<p>А.1. Ссылки на <emphasis>r</emphasis>-значения</p>

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

int var = 42;   │Создаем ссылку

int& ref = var;←┘на var

ref = 99;           │В результате присваивания ссылке

assert (var == 99);←┘изменен оригинал

Ссылки, к которым мы все давно привыкли, являются ссылками на l-значения. Термин l-значение появился еще в языке С и обозначает любую конструкцию, которая может находиться в левой части выражения присваивания, — именованные объекты, объекты, созданные в стеке или в куче, или члены других объектов, то есть сущности, расположенные по определенному адресу в памяти. Термин r-значение также происходит из С и обозначает конструкции, которые могут находиться только в правой части выражения присваивания, — например, литералы и временные объекты. Ссылки на l-значения можно связать только с l-значениями, но не с r-значениями. Так, невозможно написать

int& i = 42;

потому что 42 — это r-значение. Впрочем, это не совсем верно; всегда разрешалось связывать r-значение с константной ссылкой на l-значение:

int const& i = 42;

Однако в стандарте это исключение сделано сознательно задолго до появления ссылок на r-значения, и смысл его в том, чтобы разрешить передавать временные объекты функциям, принимающим ссылки. Благодаря этому механизму становятся возможны неявные преобразования, например, можно написать:

void print(std::string const& s);

print("hello");

Как бы то ни было, в стандарте C++11 официально введены ссылки на r-значения, которые связываются только с r-значениями, но не с l-значениями, и объявляются с помощью двух знаков амперсанда:

int&& i = 42;

int j = 42;

int&& k = j;

Таким образом, функцию можно перегрузить в зависимости от того, являются параметры l-значениями или r-значениями, — один вариант будет принимать ссылку на l-значение, другой — на r-значение. Эта возможность — краеугольный камень семантики перемещения.

<p>A.1.1. Семантика перемещения</p>

r-значения — это обычно временные объекты, поэтому их можно спокойно модифицировать; если известно, что параметр функции — r-значение, то его можно использовать как временную память, то есть «позаимствовать» его содержимое без ущерба для корректности программы. Это означает, что вместо копирования параметра, являющегося r-значением, мы можем просто переместить его содержимое. В случае больших динамических структур это позволяет сэкономить на выделении памяти и оставляет простор для оптимизации.

Рассмотрим функцию, которая принимает в качестве параметра std::vector и хочет иметь его внутреннюю копию для модификации, так чтобы не затрагивать оригинал. Раньше мы для этого должны были принимать параметр как const-ссылку на l-значение и делать внутреннюю копию:

void process_copy(std::vector const& vec_) {

 std::vector vec(vec_);

 vec.push_back(42);

}

При этом функция может принимать как l-значения, так и r-значения, но копирование производится всегда. Однако, если добавить перегруженный вариант, который принимает ссылку на r-значение, то в этом случае можно будет избежать копирования, поскольку нам точно известно, что оригинал разрешается модифицировать:

void process_copy(std::vector&& vec) {

 vec.push_back(42);

}

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных