std:: call_once
|
Défini dans l'en-tête
<mutex>
|
||
|
template
<
class
Callable,
class
...
Args
>
void call_once ( std:: once_flag & flag, Callable && f, Args && ... args ) ; |
(depuis C++11) | |
Exécute l'objet Callable f exactement une fois, même s'il est appelé simultanément depuis plusieurs threads.
En détail :
-
Si, au moment où
std::call_onceest appelé, flag indique que f a déjà été appelée,std::call_onceretourne immédiatement (un tel appel àstd::call_onceest qualifié de passif ).
-
Sinon,
std::call_onceappelle INVOKE ( std:: forward < Callable > ( f ) , std:: forward < Args > ( args ) ... ) . Contrairement au constructeur de std::thread ou à std::async , les arguments ne sont ni déplacés ni copiés car ils n'ont pas besoin d'être transférés vers un autre thread d'exécution (un tel appel àstd::call_onceest qualifié d' actif ).
-
-
Si cet appel lève une exception, elle est propagée à l'appelant de
std::call_once, et le flag n'est pas basculé de sorte qu'un autre appel sera tenté (un tel appel àstd::call_onceest qualifié d' exceptionnel ). -
Si cet appel retourne normalement (un tel appel à
std::call_onceest qualifié de retournant ), flag est basculé, et tous les autres appels àstd::call_onceavec le même flag sont garantis d'être passifs .
-
Si cet appel lève une exception, elle est propagée à l'appelant de
Tous les appels actifs sur le même flag forment un ordre total unique composé de zéro ou plusieurs appels exceptionnels , suivis d'un appel de retour . La fin de chaque appel actif se synchronise-avec le prochain appel actif dans cet ordre.
Le retour de l'appel
actif
se synchronise-avec les retours de tous les appels
passifs
sur le même
flag
: cela signifie que tous les appels concurrents à
std::call_once
sont garantis d'observer tous les effets de bord produits par l'appel
actif
, sans synchronisation supplémentaire.
Table des matières |
Paramètres
| flag | - | un objet pour lequel exactement une fonction est exécutée |
| f | - | Callable objet à invoquer |
| args... | - | arguments à passer à la fonction |
Valeur de retour
(aucun)
Exceptions
-
std::system_error
si une condition quelconque empêche les appels à
std::call_oncede s'exécuter comme spécifié. - Toute exception levée par f .
Notes
Si des appels concurrents à
std::call_once
passent différentes fonctions
f
, il n'est pas spécifié quelle
f
sera appelée. La fonction sélectionnée s'exécute dans le même thread que l'invocation
std::call_once
à laquelle elle a été passée.
L'initialisation des
variables statiques locales à une fonction
est garantie de se produire une seule fois même lorsqu'elles sont appelées depuis plusieurs threads, et peut être plus efficace que le code équivalent utilisant
std::call_once
.
L'équivalent POSIX de cette fonction est
pthread_once
.
Exemple
#include <iostream> #include <mutex> #include <thread> std::once_flag flag1, flag2; void simple_do_once() { std::call_once(flag1, [](){ std::cout << "Simple example: called once\n"; }); } void may_throw_function(bool do_throw) { if (do_throw) { std::cout << "Throw: call_once will retry\n"; // ceci peut apparaître plusieurs fois throw std::exception(); } std::cout << "Did not throw, call_once will not attempt again\n"; // garanti une seule fois } void do_once(bool do_throw) { try { std::call_once(flag2, may_throw_function, do_throw); } catch (...) {} } int main() { std::thread st1(simple_do_once); std::thread st2(simple_do_once); std::thread st3(simple_do_once); std::thread st4(simple_do_once); st1.join(); st2.join(); st3.join(); st4.join(); std::thread t1(do_once, true); std::thread t2(do_once, true); std::thread t3(do_once, false); std::thread t4(do_once, true); t1.join(); t2.join(); t3.join(); t4.join(); }
Sortie possible :
Simple example: called once Throw: call_once will retry Throw: call_once will retry Throw: call_once will retry Did not throw, call_once will not attempt again
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 2080 | C++11 |
std::invalid_argument
serait levé si
f
est invalide,
mais le scénario où f est invalidé n'est pas spécifié |
cette condition d'erreur a été supprimée |
| LWG 2442 | C++11 | les arguments étaient copiés et/ou déplacés avant l'invocation | aucune copie/déplacement n'est effectué |
Voir aussi
|
(C++11)
|
objet d'assistance pour garantir que
call_once
n'invoque la fonction qu'une seule fois
(classe) |
|
Documentation C
pour
call_once
|
|