Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - [41]
Вызывается
>X x; │
p->foo(42,"hello"),
>auto f1 = std::async(&X::foo, &x, 42, "hello");←┘
где p=&x
>auto f2 = std::async(&X::bar, x, "goodbye");←┐
вызывается
> │
tmpx.bar("goodbye"),
>struct Y { │
где tmpx — копия x
> double operator()(double);
>}; │
Вызывается tmpy(3.141),
> │
где tmpy создается
>Y y; │
из Y перемещающим
>auto f3 = std::async(Y(), 3.141)←┘
конструктором
>auto f4 = std::async(std::ref(y), 2.718);←
Вызывается y(2.718)
>X baz(X&);
>std::async(baz, std::ref(x); ←
Вызывается baz(x)
>class move_only {
>public:
> move_only();
> move_only(move_only&&);
> move_only(move_only const&) = delete;
> move_only& operator=(move_only&&);
> move_only& operator=(move_only const&) = delete;
> void operator()(); │
Вызывается tmp(), где tmp
>}; │
конструируется с помощью
>auto f5 = std::async(move_only());←┘
std::move(move_only())
По умолчанию реализации предоставлено право решать, запускает ли >std::async
новый поток или задача работает синхронно, когда программа ожидает будущего результата. В большинстве случаев такое поведение вас устроит, но можно задать требуемый режим в дополнительном параметре >std::async
перед вызываемой функцией. Этот параметр имеет тип >std::launch
и может принимать следующие значения: >std::launch::deferred
— отложить вызов функции до того момента, когда будет вызвана функция-член >wait()
или >get()
объекта-будущего; >std::launch::async
— запускать функцию в отдельном потоке; >std::launch::deferred | std::launch::async
— оставить решение на усмотрение реализации. Последний вариант подразумевается по умолчанию. В случае отложенного вызова функция может вообще никогда не выполниться. Например:
>auto f6 = │
Выполнять в
> std::async(std::launch::async, Y(), 1.2);←┘
новом потоке
>auto f7 =
> std::async(
> std::launch::deferred, baz, std::ref(x)); ←┐
>auto f8 = std::async( ←┐│
Выполнять
> std::launch::deferred | std::launch::async,││
при вызове
> baz, std::ref(x)); ││
wait() или get()
>auto f9 = std::async(baz, std::ref(x)); ←┼
Оставить на
> │
усмотрение реализации
>f7.wait();←
Вызвать отложенную функцию
Ниже в этой главе и далее в главе 8 мы увидим, что с помощью >std::async
легко разбивать алгоритм на параллельно выполняемые задачи. Однако это не единственный способ ассоциировать объект >std::future
с задачей; можно также обернуть задачу объектом шаблонного класса >std::packaged_task<>
или написать код, который будет явно устанавливать значения с помощью шаблонного класса >std::promise<>
. Шаблон >std::packaged_task
является абстракцией более высокого уровня, чем >std::promise
, поэтому начнем с него.
4.2.2. Ассоциирование задачи с будущим результатом
Шаблон класса >std::packaged_task<>
связывает будущий результат с функцией или объектом, допускающим вызов. При вызове объекта >std::packaged_task<>
ассоциированная функция или допускающий вызов объект вызывается и делает будущий результат готовым, сохраняя возвращенное значение в виде ассоциированных данных. Этот механизм можно использовать для построение пулов потоков (см. главу 9) и иных схем управления, например, запускать каждую задачу в отдельном потоке или запускать их все последовательно в выделенном фоновом потоке. Если длительную операцию можно разбить на автономные подзадачи, то каждую из них можно обернуть объектом >std::packaged_task<>
и передать этот объект планировщику задач или пулу потоков. Таким образом, мы абстрагируем специфику задачи — планировщик имеет дело только с экземплярами >std::packaged_task<>
, а не с индивидуальными функциями.
Параметром шаблона класса >std::packaged_task<>
является сигнатура функции, например >void()
для функции, которая не принимает никаких параметров и не возвращает значения, или >int(std::string&, double*)
для функции, которая принимает неконстантную ссылку на >std::string
и указатель на >double
и возвращает значение типа >int
. При конструировании экземпляра >std::packaged_task
вы обязаны передать функцию или допускающий вызов объект, который принимает параметры указанных типов и возвращает значение типа, преобразуемого в указанный тип возвращаемого значения. Точного совпадения типов не требуется; можно сконструировать объект >std::packaged_task
из функции, которая принимает >int
и возвращает >float
, потому что между этими типами существуют неявные преобразования.
Тип возвращаемого значения, указанный в сигнатуре функции, определяет тип объекта >std::future<>
, возвращаемого функцией-членом >get_future()
, а заданный в сигнатуре список аргументов используется для определения сигнатуры оператора вызова в классе упакованной задачи. Например, в листинге ниже приведена часть определения класса >std::packaged_task
.
Листинг 4.8. Определение частичной специализации >std::packaged_task
>template<>
>class packaged_task

Это знаменитый бестселлер, который научит вас использовать власть массового сотрудничества и покажет, как применять викиномику в вашем бизнесе. Переведенная более чем на двадцать языков и неоднократно номинированная на звание лучшей бизнес-книги, "Викиномика" стала обязательным чтением для деловых людей во всем мире. Она разъясняет, как массовое сотрудничество происходит не только на сайтах Wikipedia и YouTube, но и в традиционных компаниях, использующих технологии для того, чтобы вдохнуть новую жизнь в свои предприятия.Дон Тапскотт и Энтони Уильямс раскрывают принципы викиномики и рассказывают потрясающие истории о том, как массы людей (как за деньги, так и добровольно) создают новости, изучают геном человека, создают ремиксы любимой музыки, находят лекарства от болезней, редактируют школьные учебники, изобретают новую косметику, пишут программное обеспечение и даже строят мотоциклы.Знания, ресурсы и вычислительные способности миллиардов людей самоорганизуются и превращаются в новую значительную коллективную силу, действующую согласованно и управляемую с помощью блогов, вики, чатов, сетей равноправных партнеров и личные трансляции.

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)

Что такое ГЕЙМДИЗАЙН? Это не код, графика или звук. Это не создание персонажей или раскрашивание игрового поля. Геймдизайн – это симулятор мечты, набор правил, благодаря которым игра оживает. Как создать игру, которую полюбят, от которой не смогут оторваться? Знаменитый геймдизайнер Тайнан Сильвестр на примере кейсов из самых популярных игр рассказывает как объединить эмоции и впечатления, игровую механику и мотивацию игроков. Познакомитесь с принципами дизайна, которыми пользуются ведущие студии мира! Создайте игровую механику, вызывающую эмоции и обеспечивающую разнообразие.

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

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

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

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.