Мы с вами рассмотрели
множество способов ускорения программ на C++.
Мы изучили асимптотики алгоритмов и научились их
оценивать и выбирать алгоритмы с наиболее подходящей асимптотикой.
Мы узнали, что константа при асимптотике также важна и научились ее
оптимизировать за счет применения семантики перемещения и более
эффективного использования линейных контейнеров или выбора наиболее
подходящего для нашей задачи линейного контейнера.
Но что же делать, если мы вот все это уже проделали,
но наша программа все равно работает недостаточно быстро?
В этом случае ее можно распараллелить.
В конце концов уже много лет современные процессоры для
компьютеров выпускаются с несколькими ядрами,
которые позволяют параллельно выполнять различные наборы инструкций.
И поэтому сейчас умение писать многопоточные
параллельные программы является необходимым навыком для программиста.
Однако прежде чем мы перейдем к рассмотрению,
как на современном C++ создавать многопоточные программы,
давайте познакомимся с концепцией асинхронных вычислений.
Она нам потом пригодится.
Итак, давайте представим, что у вас есть костюм, и этот костюм испачкался.
Что вам надо сделать?
Вам надо его почистить, поэтому вы идете в химчистку, относите туда свой костюм,
сдаете его на чистку и взамен получаете талон.
Пока костюм чистится в химчистке,
вы можете заниматься своими делами: вы можете поехать домой и несколько дней
ходить на работу, на учебу, в общем, заниматься своей обычной деятельностью.
И через несколько дней вы приходите в химчистку и забираете свой чистый костюм.
Так как чистка костюма вас не блокирует,
то есть она позволяет вам заниматься чем-то другим, пока костюм чистится,
то мы можем говорить, что чистка костюма выполняется асинхронно.
Вот если бы этот костюм был нашей единственной одеждой, которая у нас есть,
и мы пришли в химчистку, сняли его с себя, отдали на чистку и сидим ждем,
пока нам вернут единственную одежду, которая у нас есть,
вот в этом случае для нас чистка костюма была бы синхронной,
потому что она бы нас блокировала: мы не могли заниматься ничем,
пока наш костюм чистится.
Но так как мы решили,
что мы свободны, можем несколько дней заниматься своими делами,
то в этом случае чистка костюма выполняется асинхронно.
Теперь давайте обратим внимание на талон,
который нам выдают в химчистке.
Что мы с ним можем делать?
Например, мы можем периодически приходить в химчистку, раз в день, например,
показывать талон и спрашивать, готов ли, почищен ли костюм по этому талону.
И нам будут говорить: готов — не готов.
Что еще мы можем сделать?
Мы можем сесть возле химчистки с этим талоном и ждать,
когда наш костюм почистят.
И, наконец, когда костюм почистили,
мы обмениваем талон на чистый костюм.
Таким образом, этот талон является способом взаимодействия с
результатом асинхронной операции: у нас есть результат асинхронной
операции — чистый костюм — и мы с помощью талона с ним взаимодействием.
Мы узнаем, готово — не готово, и, в конечном итоге, мы с помощью талона
получаем свой костюм назад, то есть получаем результат асинхронной операции.
Поэтому талон является примером абстракции,
которая называется future — будущее.
Эта абстракция используется при асинхронных вычислениях,
чтобы получать результат асинхронной операции.
Теперь давайте сделаем один шаг по направлению к
коду на C++ и посмотрим на вот такой схематических пример.
Что мы из него видим?
Что в C++ асинхронная операция запускается с помощью функции async.
Вот она у меня здесь указана, async.
Эта функция принимает другую функцию, которую она, собственно,
запустит асинхронно.
В данном случае мы в функцию async передаем некую функцию,
результатом которой является чистый костюм, она возвращает нам чистый костюм.
Функция async возвращает объект.
Вот эта переменная, талон является как бы именем этой переменной.
Он имеет тип future от чистого костюма.
Мы говорили, что талон — это future на чистый костюм.
Вот так схематически выглядит запуск асинхронных операций в C++: функция async,
которая возвращает future на результат функции, переданной в нее.
В следующем видео мы посмотрим,
как уже на честном C++ запускать и выполнять асинхронные операции.