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

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

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

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

Интервал:

Закладка:

Сделать

Листинг 4.7.Передача аргументов функции, заданной в std::async

#include

#include

struct X {

void foo(int, std::string const&);

std::string bar(std::string const&);

};

Вызывается

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*, int)>.

Листинг 4.8.Определение частичной специализации std::packaged_task

template<>

class packaged_task*, int)> {

public:

template

explicit packaged_task(Callable&& f);

std::future get_future();

void operator()(std::vector*, int);

};

Таким образом, std::packaged_task— допускающий вызов объект, и, значит, его можно обернуть объектом std::function, передать std::threadв качестве функции потока, передать любой другой функции, которая ожидает допускающий вызов объект, или даже вызвать напрямую. Если std::packaged_taskвызывается как объект-функция, то аргументы, переданные оператору вызова, без изменения передаются обернутой им функции, а возвращенное значение сохраняется в виде асинхронного результата в объекте std::future, полученном от get_future(). Следовательно, мы можем обернуть задачу в std::packaged_taskи извлечь будущий результат перед тем, как передавать объект std::packaged_taskв то место, из которого он будет в свое время вызван. Когда результат понадобится, нужно будет подождать готовности будущего результата. В следующем примере показано, как всё это делается на практике.

Передача задач между потоками

Во многих каркасах для разработки пользовательского интерфейса требуется, чтобы интерфейс обновлялся только в специально выделенных потоках. Если какому-то другому потоку потребуется обновить интерфейс, то он должен послать сообщение одному из таких выделенных потоков, чтобы тот выполнил операцию. Шаблон std::packaged_taskпозволяет решить эту задачу, не заводя специальных сообщений для каждой относящейся к пользовательскому интерфейсу операции.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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