std::promise în C++

Capătul de scriere al unui std::future: un fir promite o valoare și o trimite cu set_value.

Sintaxă
#include <future>
std::promise<T> p;
std::future<T> get_future();
void set_value(T valoare);
void set_exception(std::exception_ptr e);

Ce face std::promise

std::promise<T> și std::future<T> formează un canal cu o singură utilizare. Firul care calculează primește promise-ul și apelează set_value(v); firul care așteaptă ține future-ul obținut cu get_future() și apelează get().

În loc de valoare, se poate trimite o excepție cu set_exception(std::current_exception()). Dacă promise-ul este distrus fără să trimită nimic, get() aruncă std::future_error („broken promise”).

Folosește-l când rezultatul nu vine dintr-un simplu apel de funcție (altfel std::async este mai simplu), de exemplu când firul trimite o valoare la mijlocul lucrului și continuă.

Ce returnează

get_future() returnează std::future<T> (se poate apela o singură dată).

Exemple

Exemplul 1: Un fir trimite rezultatul

#include <functional>
#include <future>
#include <print>
#include <thread>
#include <vector>

void medie(const std::vector<double>& note, std::promise<double> p) {
    double suma = 0;
    for (double n : note) suma += n;
    p.set_value(suma / static_cast<double>(note.size()));
}

int main() {
    std::vector<double> note{9, 8.5, 10, 7};
    std::promise<double> p;
    std::future<double> rezultat = p.get_future();

    std::thread t(medie, std::cref(note), std::move(p));
    std::println("Media: {}", rezultat.get());
    t.join();
}

Rezultat

Media: 8.625

Exemplul 2: Trimiterea unei excepții

#include <exception>
#include <future>
#include <print>
#include <stdexcept>
#include <thread>

int main() {
    std::promise<int> p;
    auto f = p.get_future();

    std::thread t([&p] {
        try {
            throw std::runtime_error("senzor deconectat");
        } catch (...) {
            p.set_exception(std::current_exception());
        }
    });

    try {
        std::println("Temperatura: {}", f.get());
    } catch (const std::exception& e) {
        std::println("Eroare din fir: {}", e.what());
    }
    t.join();
}

Rezultat

Eroare din fir: senzor deconectat

Greșeli frecvente

  • Apelezi set_value de două ori. A doua oară se aruncă std::future_error („promise already satisfied”).
  • Dai promise-ul unui fir prin copiere. Nu compilează: std::promise se poate doar muta (std::move(p)).

Comenzi înrudite

  • std::future: Un rezultat care va fi disponibil în viitor (de la std::async sau std::promise); get() îl așteaptă și îl returnează.
  • std::async: Rulează o funcție (de obicei pe alt fir) și îți dă un std::future din care iei rezultatul mai târziu.
  • std::current_exception: Salvează excepția prinsă într-un exception_ptr, ca să fie aruncată din nou mai târziu, chiar pe alt fir.
  • std::thread: Pornește o funcție pe un fir de execuție separat, care rulează în paralel cu restul programului.