Ce face std::call_once
std::call_once(steag, f) apelează f doar prima dată pentru un anumit std::once_flag. Dacă mai multe fire ajung în același timp, unul rulează funcția, iar celelalte așteaptă până termină, apoi continuă fără s-o mai ruleze.
Este util pentru inițializări leneșe (conexiune, configurație) în cod cu mai multe fire. Dacă funcția aruncă o excepție, steagul rămâne nesetat și următorul apel încearcă din nou.
Pentru o variabilă locală static, C++11 garantează deja inițializarea o singură dată, sigur pentru fire; acolo nu ai nevoie de call_once.
Parametri
| Parametru | Descriere |
|---|---|
steag |
Un std::once_flag care ține minte dacă funcția a rulat. |
functie, argumente |
Funcția apelată și argumentele ei. |
Ce returnează
Nimic.
Exemple
Exemplul 1: Configurația se încarcă o singură dată
Patru fire cer configurația, dar mesajul „Încarc” apare o singură dată.
#include <mutex>
#include <print>
#include <string>
#include <thread>
#include <vector>
std::once_flag configIncarcata;
std::string config;
void incarcaConfig() {
std::println("Încarc configurația...");
config = "limba=ro";
}
int main() {
std::vector<std::thread> fire;
for (int i = 0; i < 4; ++i) {
fire.emplace_back([] { std::call_once(configIncarcata, incarcaConfig); });
}
for (auto& t : fire) t.join();
std::println("Config: {}", config);
}
Rezultat
Încarc configurația...
Config: limba=ro
Greșeli frecvente
- Folosești un
boolobișnuit (if (!incarcat) { incarca(); incarcat = true; }) cu mai multe fire. Două fire pot trece de verificare în același timp și inițializarea rulează de două ori.
Comenzi înrudite
std::mutex: Încuietoare pentru date comune: un singur fir de execuție o poate ține la un moment dat.static: Are trei sensuri: variabilă locală care își păstrează valoarea între apeluri, membru comun al clasei sau nume vizibil doar în fișierul curent.std::thread: Pornește o funcție pe un fir de execuție separat, care rulează în paralel cu restul programului.