Ежедневный бит (е) C++ # 26, одноразовые инструменты C++ 11 производитель-потребитель, std::promise и std::future

C++ не предлагает много высокоуровневых средств синхронизации потоков и связи. Одним из немногих является пара std::promise и std::future.

std::promise и std::future реализуют одноразовую семантику производитель-потребитель.

Потребитель (std::future) может блокироваться до тех пор, пока не будет доступен результат производителя (std::promise), после чего можно будет получить доступ к произведенному значению.

#include <future>
#include <thread>
#include <iostream>
#include <stdexcept>
using namespace std::literals;

std::promise<std::string> promise;
// Future is obtained from the promise.
std::future<std::string> future = promise.get_future();
auto t = std::jthread([promise = std::move(promise)] mutable {
    std::this_thread::sleep_for(100ms);
    // Set the value, this will unblock the consumer (future).
    promise.set_value("Hello World!"s);
    // If it is preferable to block until this thread finishes:
    // promise.set_value_at_thread_exit("Hello World!"s);
});

// Will block until value awailable, 
// then returns the stored value:
std::cout << future.get() << "\n";
// Will print: "Hello World!"

// Promise/Future can also propagate exceptions:
std::promise<int> other;
std::future<int> will_fail = other.get_future();
auto f = std::jthread([promise = std::move(other)] mutable {
    try {
        throw std::runtime_error("Some error happened.");
        promise.set_value(10); // unreachable
    } catch (...) {
        promise.set_exception(std::current_exception());
        // same as before we can also:
        // set_exception_at_thread_exit(...);
    }        
});

try {
    // Block until value awailable, in this case,
    // the exception will be propagated instead.
    int v = will_fail.get();
    std::cout << "This will not print " << v << "\n";
} catch (const std::exception& e) {
    std::cout << "Propagated exception: " << e.what() << "\n";
}
// Will print: "Propagated exception: Some error happened."

Откройте этот пример в Compiler Explorer.