Ce face std::async
std::async este cel mai simplu mod de a rula ceva în paralel și de a primi înapoi un rezultat. Returnează un std::future; când ai nevoie de rezultat, apelezi get(), care așteaptă dacă funcția nu a terminat încă.
Primul parametru alege modul: std::launch::async pornește un fir nou imediat; std::launch::deferred amână execuția până la get(), pe firul care cere rezultatul. Fără acest parametru, implementarea alege singură; pentru paralelism real, scrie explicit std::launch::async.
Dacă funcția aruncă o excepție, aceasta este păstrată și aruncată din nou la get().
Parametri
| Parametru | Descriere |
|---|---|
std::launch::async / deferred |
Opțional: modul de lansare. |
functie, argumente |
Ce se rulează; argumentele sunt copiate. |
Ce returnează
Un std::future<R>, unde R este tipul returnat de funcție.
Exemple
Exemplul 1: Două calcule în paralel
#include <functional>
#include <future>
#include <numeric>
#include <print>
#include <vector>
long long suma(const std::vector<int>& v, std::size_t de, std::size_t pana) {
return std::accumulate(v.begin() + de, v.begin() + pana, 0LL);
}
int main() {
std::vector<int> vanzari(10'000, 3);
auto prima = std::async(std::launch::async, suma, std::cref(vanzari), 0, 5'000);
auto aDoua = std::async(std::launch::async, suma, std::cref(vanzari), 5'000, 10'000);
std::println("Total: {}", prima.get() + aDoua.get());
}
Rezultat
Total: 30000
Exemplul 2: Excepția ajunge la get()
#include <future>
#include <print>
#include <stdexcept>
#include <string>
std::string descarca(const std::string& adresa) {
if (adresa.empty()) throw std::invalid_argument("adresă goală");
return "conținutul de la " + adresa;
}
int main() {
auto bun = std::async(std::launch::async, descarca, "dexblog.ro");
auto rau = std::async(std::launch::async, descarca, "");
std::println("{}", bun.get());
try {
std::println("{}", rau.get());
} catch (const std::exception& e) {
std::println("Eroare: {}", e.what());
}
}
Rezultat
conținutul de la dexblog.ro
Eroare: adresă goală
Greșeli frecvente
- Ignori valoarea returnată:
std::async(std::launch::async, f);. Destructorulfuture-ului temporar așteaptă imediat terminarea, deci nu rulează nimic în paralel (iar compilatorul avertizează, pentru că rezultatul este[[nodiscard]]). - Apelezi
get()de două ori pe acelașistd::future. După primul apel,future-ul devine invalid; pentru mai mulți cititori foloseștestd::shared_future.
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::promise: Capătul de scriere al unui std::future: un fir promite o valoare și o trimite cu set_value.std::thread: Pornește o funcție pe un fir de execuție separat, care rulează în paralel cu restul programului.std::ref: Împachetează o referință ca să poată fi transmisă prin funcții care copiază argumentele (thread, bind).