std async std future std promise std packagedtask






![std: : packaged_task<void()> task{ []{ boil. Water(); make. Tea(); } }; std: : future<void> std: : packaged_task<void()> task{ []{ boil. Water(); make. Tea(); } }; std: : future<void>](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-7.jpg)





![Task unwrapping task<void> make. Tea. Async(); auto tea = task<void>{[]() -> task<void> { boil. Task unwrapping task<void> make. Tea. Async(); auto tea = task<void>{[]() -> task<void> { boil.](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-13.jpg)
![Continuations task<std: : string> water = create_task([] { boil. Water(); return "Water boiled"s; }); Continuations task<std: : string> water = create_task([] { boil. Water(); return "Water boiled"s; });](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-14.jpg)
![Обработка исключений auto tea = create_task([]() -> int { BANG! throw std: : runtime_error{ Обработка исключений auto tea = create_task([]() -> int { BANG! throw std: : runtime_error{](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-15.jpg)
![Cancellation cancellation_token_source token. Source; create_task([token = token. Source. get_token()] { boil. Water(); if (token. Cancellation cancellation_token_source token. Source; create_task([token = token. Source. get_token()] { boil. Water(); if (token.](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-16.jpg)
![Cancellation callback void boil. Water(cancellation_token) { const auto registration = token. register_callback([] { stop. Cancellation callback void boil. Water(cancellation_token) { const auto registration = token. register_callback([] { stop.](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-17.jpg)


 { return create_task(func). then([func](bool need.](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-20.jpg)






















![легковесный Task struct [[nodiscard]] Task { using promise_type = Task. Promise; Task(coroutine_handle<Task. Promise> coro) легковесный Task struct [[nodiscard]] Task { using promise_type = Task. Promise; Task(coroutine_handle<Task. Promise> coro)](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-43.jpg)


- Slides: 45


О чём речь • std: : async, std: : future, std: : promise, std: : packaged_task • PPL: concurrency: : task, continuations, cancellation, task composition • корутины: co_await, co_return, генераторы, детали реализации • будущее? 2



Метафора Асинхронный вариант: kettle. boil. Water. Async(); play. Videogames. For(5 min); kettle. wait. Water. To. Boil(); make. Tea. Async(); watch. You. Tube. For(2 min); drink. Tea(); 5

std: : async std: : future<void> tea = std: : async(std: : launch: : async, []{ boil. Water(); make. Tea(); }); watch. People. Play. Games. On. You. Tube. For(7 min); tea. get(); drink. Tea(); 6
![std packagedtaskvoid task boil Water make Tea std futurevoid std: : packaged_task<void()> task{ []{ boil. Water(); make. Tea(); } }; std: : future<void>](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-7.jpg)
std: : packaged_task<void()> task{ []{ boil. Water(); make. Tea(); } }; std: : future<void> tea = task. get_future(); help. execute(std: : move(task)); tea. get(); drink. Tea(); 7

std: : promise<int> promise; std: : future<int> tea = promise. get_future(); auto task = [p = std: : move(promise)]() mutable { try { std: : promise boil. Water(); shared state make. Tea(); p. set_value(42); std: : future } catch (. . . ) { p. set_exception(std: : current_exception()); } }; help. execute(std: : move(task)); tea. get(); 8

Идиома: асинхронное обновление значения struct Widget { std: : future<void> update. Value(); std: : string get. Value() const; private: struct State { std: : mutex; std: : string value; }; std: : shared_ptr<State> m_state = std: : make_shared<State>(); }; std: : future<void> Widget: : update. Value() { return std: : async( [state. Ptr = std: : weak_ptr{m_state}] { auto new. Value = get. Updated. Value(); if (auto state = state. Ptr. lock()) { std: : lock_guard lock(state->mutex); state->value = std: : move(new. Value); } }); } std: : string Widget: : get. Value() const { std: : lock_guard lock(m_state->mutex); return m_state->value; } 9

Parallel Patterns Library • выпущена Microsoft вместе с Visual Studio 2010 (+ лямбды) • подмножество (PPLX) реализовано в кроссплатформенной библиотеке C++ REST SDK https: //github. com/Microsoft/cpprestsdk 10

PPL concurrency: : task 101 #include <ppltasks. h> #include <future> using namespace concurrency; task<T> std: : future<T> auto t = task<T>{f}; auto t = create_task(f); auto t = std: : async( std: : launch: : async, f); task_completion_event<T> std: : promise<T> 11

Task unwrapping std: : future<void> make. Tea. Async(); std: : future<void>> tea = std: : async([]() -> std: : future<void> { boil. Water(); return make. Tea. Async(); } ); tea. get(); drink. Tea(); 12
![Task unwrapping taskvoid make Tea Async auto tea taskvoid taskvoid boil Task unwrapping task<void> make. Tea. Async(); auto tea = task<void>{[]() -> task<void> { boil.](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-13.jpg)
Task unwrapping task<void> make. Tea. Async(); auto tea = task<void>{[]() -> task<void> { boil. Water(); return make. Tea. Async(); } }; tea. wait(); drink. Tea(); 13
![Continuations taskstd string water createtask boil Water return Water boileds Continuations task<std: : string> water = create_task([] { boil. Water(); return "Water boiled"s; });](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-14.jpg)
Continuations task<std: : string> water = create_task([] { boil. Water(); return "Water boiled"s; }); task<void> tea = water. then( [](const std: : string &msg) { make. Tea(); }); tea. wait(); 14
![Обработка исключений auto tea createtask int BANG throw std runtimeerror Обработка исключений auto tea = create_task([]() -> int { BANG! throw std: : runtime_error{](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-15.jpg)
Обработка исключений auto tea = create_task([]() -> int { BANG! throw std: : runtime_error{ "BANG!" }; }). then([](const task<int> &t) { BANG! t. get(); boil. Water(); return "Water boiled"s; }). then([](const std: : string &msg) { make. Tea(); }); BANG! tea. wait(); 15
![Cancellation cancellationtokensource token Source createtasktoken token Source gettoken boil Water if token Cancellation cancellation_token_source token. Source; create_task([token = token. Source. get_token()] { boil. Water(); if (token.](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-16.jpg)
Cancellation cancellation_token_source token. Source; create_task([token = token. Source. get_token()] { boil. Water(); if (token. is_canceled()) cancel_current_task(); //throws task_canceled{} make. Tea(); Использование: }) token. Source. cancel(); . wait(); 16
![Cancellation callback void boil Watercancellationtoken const auto registration token registercallback stop Cancellation callback void boil. Water(cancellation_token) { const auto registration = token. register_callback([] { stop.](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-17.jpg)
Cancellation callback void boil. Water(cancellation_token) { const auto registration = token. register_callback([] { stop. Boiling(); предложение P 0660 }); в стандарт C++ boil. Water(); token. deregister_callback(registration); } 17

Task composition: when_all task<std: : string> boil. Water. And. Make. Tea. Async(); task<std: : string> make. Sandwich. Async(); task<std: : string> tasks[] = { boil. Water. And. Make. Tea. Async(), make. Sandwich. Async() возвращает результаты задач }; task<std: : vector<std: : string>> result = when_all(std: : begin(tasks), std: : end(tasks)); 18

Task composition: when_any task<std: : string> boil. Water. And. Make. Tea. Async(); task<std: : string> make. Sandwich. Async(); task<std: : string> tasks[] = { boil. Water. And. Make. Tea. Async(), make. Sandwich. Async() возвращает результат задачи и её индекс }; task<std: : pair<std: : string, size_t>> result = when_any(std: : begin(tasks), std: : end(tasks)); 19

Идиома: do while template<typename Func> task<void> do. While(Func func) { return create_task(func). then([func](bool need. To. Continue) { if (need. To. Continue) return do. While(func); return task_from_result(); } 20

Идиома: отмена нескольких запросов task<std: : string> make. Request(const std: : string &request, cancellation_token); struct Gadget { task<std: : string> make. Request(const std: : string &request) { return make. Request(request, m_token. Source. get_token()); } void cancel. All. Requests() { m_token. Source. cancel(); m_token. Source = {}; } private: cancellation_token_source m_token. Source; }; 21

Идиома: continuation chaining auto avatar = http: : client: : http_client{"https: //reqres. in"}. request(http: : methods: : GET, "/api/users/1"). then([](const http: : http_response &response) { if (response. status_code() != http: : status_codes: : OK) throw std: : runtime_error("Failed to get user"); return response. extract_json(); }). then([](const json: : value &response) { const auto url = response. at("data"). at("avatar"). as_string(); return http: : client: : http_client(url). request(http: : methods: : GET); }). then([](const concurrency: : task<http: : http_response> &result) { const auto response = result. get(); if (response. status_code() != http: : status_codes: : OK) throw std: : runtime_error("Failed to get avatar"); return response. extract_vector(); }); 22

https: //isocpp. org/std/status 23

Зачем мне корутины? task<void> boil. Water. Async(); task<void> make. Tea. Async(); task<std: : string> boil. Water. And. Make. Tea. Async() { return boil. Water. Async(). then([] { return make. Tea. Async(); }). then([] { return "tea ready"s; }); } 24

Зачем мне корутины? task<void> boil. Water. Async(); task<void> make. Tea. Async(); task<std: : string> boil. Water. And. Make. Tea. Async() { co_await boil. Water. Async(); } co_await make. Tea. Async(); co_return "tea ready"; 25

auto avatar = http: : client: : http_client{"https: //reqres. in"}. request(http: : methods: : GET, "/api/users/1"). then([](const http: : http_response &response) { if (response. status_code() != http: : status_codes: : OK) throw std: : runtime_error("Failed to get user"); return response. extract_json(); }). then([](const json: : value &response) { const auto url = response. at("data"). at("avatar"). as_string(); return http: : client: : http_client(url). request(http: : methods: : GET); }). then([](const concurrency: : task<http: : http_response> &result) { const auto response = result. get(); if (response. status_code() != http: : status_codes: : OK) throw std: : runtime_error("Failed to get avatar"); return response. extract_vector(); }); 26

const http: : http_response user. Response = co_await http: : client: : http_client{"https: //reqres. in"}. request(http: : methods: : GET, "/api/users/1"); if (user. Response. status_code() != http: : status_codes: : OK) throw std: : runtime_error("Failed to get user"); const json: : value json. Response = co_await user. Response. extract_json(); const auto url = json. Response. at("data"). at("avatar"). as_string(); const http: : http_response avatar. Response = co_await http: : client: : http_client{url}. request(http: : methods: : GET); if (avatar. Response. status_code() != http: : status_codes: : OK) throw std: : runtime_error("Failed to get avatar"); auto avatar = co_await avatar. Response. extract_vector(); 27

Зачем мне генераторы? std: : generator<std: : string> stop. Gort( std: : string suffix) { co_yield "Klaatu" + suffix; co_yield "barada" + suffix; co_yield "nikto" + suffix; } auto words = stop. Gort(", please"); for (auto i : words) std: : cout << i << 'n'; 28

Зачем мне генераторы? std: : generator<int> fibonacci() { for (int cur = 0, next = 1; ; ) { co_yield cur; cur = std: : exchange(next, cur + next); } } for (auto n : fibonacci()) std: : cout << n << 'n'; 29



Что происходит "за кулисами" co_await boil. Water. Async(); из контекста корутины //std: : experimental: : coroutine_handle<> coroutine. Handle; auto awaitable = operator co_await(boil. Water. Async()); if (!awaitable. await_ready()) { awaitable. await_suspend(coroutine. Handle); //suspend & resume } запланировать продолжение вернуть значение awaitable. await_resume(); 32

Что происходит "за кулисами" task<std: : string> boil. Water. And. Make. Tea. Async() { co_await boil. Water. Async(); co_await make. Tea. Async(); co_return "tea ready"; } 33

Что происходит "за кулисами" task<std: : string> boil. Water. And. Make. Tea. Async() { auto p = std: : coroutine_traits<task<std: : string>>: : promise_type{}; auto return. Object = p. get_return_object(); co_await p. initial_suspend(); часть контекста корутины try { возвращается на co_await boil. Water. Async(); //suspend & resume первой приостановке co_await make. Tea. Async(); //suspend & resume p. return_value("tea ready"); goto final_suspend; //co_return } catch (. . . ) { p. unhandled_exception(); } final_suspend: co_await p. final_suspend(); 34 }

Что происходит "за кулисами" co_yield expression; co_await promise. yield_value(expression); 35

Gotta go faster 36


Benchmark: std: : future void future(benchmark: : State& state) { for (auto i : state) { std: : future<void> water = std: : async(std: : launch: : deferred, [] { boil. Water(); }); auto tea = std: : async(std: : launch: : deferred, [water = std: : move(water)]() mutable { water. get(); make. Tea(); }); время=541 нс tea. get(); скорость=1 x } } BENCHMARK(future); 38

Benchmark: concurrency: : task void concurrency. Task(benchmark: : State& state) { for (auto i : state) { [] { boil. Water(); return concurrency: : task_from_result(); }(). then([] { make. Tea(); }) время=7195 нс. wait(); } скорость=0, 08 x } BENCHMARK(concurrency. Task); 39

Benchmark: легковесный Task boil. Water. Async() { boil. Water(); co_return; } Task make. Tea. Async() { make. Tea(); co_return; } void coroutines(benchmark: : State& state) { [&state]() -> std: : future<void> { for (auto i : state) { co_await boil. Water. Async(); co_await make. Tea. Async(); время=204 нс } скорость=2, 7 x }(). wait(); } BENCHMARK(coroutines); 40

Benchmark Run on (4 X 3392 MHz CPU s) CPU Caches: L 1 Data 32 K (x 4) L 1 Instruction 32 K (x 4) L 2 Unified 262 K (x 4) L 3 Unified 6291 K (x 1) ---------------------------Benchmark Time CPU Iterations ---------------------------future 541 ns 547 ns 1000000 concurrency. Task 7195 ns 7254 ns 112000 coroutines 204 ns 3446154 raw. Calls 1 ns 100000 41

легковесный Task struct Task. Promise { struct Task get_return_object(); bool initial_suspend() { return false; } auto final_suspend() { struct Awaitable { bool await_ready() { return false; } void await_suspend(std: : coroutine_handle<Task. Promise> coro) { if (auto continuation = coro. promise(). continuation) continuation. resume(); } void await_resume() {} }; return Awaitable{}; } void unhandled_exception() { exception = std: : current_exception(); } void return_void() {} void result() { if (exception) std: : rethrow_exception(exception); } std: : coroutine_handle<> continuation; std: : exception_ptr exception; }; 42
![легковесный Task struct nodiscard Task using promisetype Task Promise TaskcoroutinehandleTask Promise coro легковесный Task struct [[nodiscard]] Task { using promise_type = Task. Promise; Task(coroutine_handle<Task. Promise> coro)](https://slidetodoc.com/presentation_image/2bd5373ef6776452f0b18007ea4f8b23/image-43.jpg)
легковесный Task struct [[nodiscard]] Task { using promise_type = Task. Promise; Task(coroutine_handle<Task. Promise> coro) : m_coro(coro) {} ~Task() { if (m_coro) m_coro. destroy(); } friend auto operator co_await(const Task &t) { struct Awaitable { bool await_ready() { return coro. done(); } void await_suspend(coroutine_handle<> coro) { this->coro. promise(). continuation = coro; } void await_resume() { coro. promise(). result(); } coroutine_handle<Task. Promise> coro; }; return Awaitable{ t. m_coro }; } private: coroutine_handle<Task. Promise> m_coro; }; Task. Promise: : get_return_object() { return Task{ coroutine_handle<Task. Promise>: : from_promise(*this) }; } 43


C# async void vs async task
Std async
Future perfect simple continuous
The future continuous and future perfect
Think async
Delphi high performance
Connection-oriented
Ajax async
Async-sema
Async task
Ajax framework
Async void c#
Async await state machine
Perfect future tense
Present progressive for plans
Future continuous and future perfect objasnjenje
Future perfect future continuous exercises
Tense chart for 6th class
Tenses chart
Future nurse future midwife e learning
Future plans and finished future actions
Past continuous to future continuous
Future continuous vs future perfect
Promise of purpose
The seven dispensation
Exporting importing and countertrade
Capable to promise
Promise paul the sorcerer's apprentice
Stalin promise free elections
The cub scout promise
Cubs and bulbuls activities
Put first things first
What promise did ellen make to annemarie
Promise joshua
Girl scout promise and law
Delivering the nuclear promise
Lagerkapo definition
Promise zone evansville
Ddbss
Consumer behavior chapter 1
αλεξανδρα κολεσνικ
Solemn promises
Abigail's promise fallacy
Tn promise login
What does hrothgar promise beowulf
Did god promise abraham