L'expression «survient avant» est utilisée plusieurs fois dans le projet de norme C ++.
Par exemple: Résiliation [basic.start.term] / 5
Si l'achèvement de l'initialisation d'un objet avec une durée de stockage statique se produit fortement avant un appel à std :: atexit (voir, [support.start.term]), l'appel à la fonction est passé à std :: atexit est séquencé avant l'appel au destructeur de l'objet. Si un appel à std :: atexit se produit fortement avant la fin de l'initialisation d'un objet avec une durée de stockage statique, l'appel au destructeur de l'objet est séquencé avant l'appel à la fonction passé à std :: atexit . Si un appel à std :: atexit se produit fortement avant un autre appel à std :: atexit, l'appel à la fonction passé au deuxième appel std :: atexit est séquencé avant l'appel à la fonction passé au premier appel std :: atexit.
Et défini dans les courses de données [intro.races] / 12
Une évaluation A se produit fortement avant une évaluation D si, soit
(12.1) A est séquencé avant D, ou
(12.2) A se synchronise avec D, et A et D sont des opérations atomiques séquentiellement cohérentes ([atomics.order]), ou
(12.3) il existe des évaluations B et C telles que A est séquencé avant B, B se produit simplement avant C, et C est séquencé avant D, ou
(12.4) il y a une évaluation B telle que A se produit fortement avant B, et B se produit fortement avant D.
[Remarque: officieusement, si A se produit fortement avant B, alors A semble être évalué avant B dans tous les contextes. Se produit fortement avant d'exclure les opérations de consommation. - note de fin]
Pourquoi «cela se produit-il avant» a été introduit? Intuitivement, quelle est sa différence et sa relation avec "qui se passe avant"?
Que signifie «A semble être évalué avant B dans tous les contextes» dans la note?
(Remarque: la motivation de cette question sont les commentaires de Peter Cordes sous cette réponse .)
Projet de devis standard supplémentaire (merci à Peter Cordes)
Ordre et cohérence [atomics.order] / 4
Il existe un seul ordre total S sur toutes les opérations memory_order :: seq_cst, y compris les clôtures, qui satisfait les contraintes suivantes. Premièrement, si A et B sont des opérations memory_order :: seq_cst et A se produit fortement avant B, alors A précède B dans S. Deuxièmement, pour chaque paire d'opérations atomiques A et B sur un objet M, où A est ordonné par cohérence avant B, les quatre conditions suivantes doivent être remplies par S:
(4.1) si A et B sont tous deux des opérations memory_order :: seq_cst, alors A précède B dans S; et
(4.2) si A est une opération memory_order :: seq_cst et B se produit avant une clôture memory_order :: seq_cst Y, alors A précède Y dans S; et
(4.3) si une clôture memory_order :: seq_cst X se produit avant que A et B ne soient une opération memory_order :: seq_cst, alors X précède B dans S; et
(4.4) si une barrière memory_order :: seq_cst X se produit avant A et B se produit avant une barrière memory_order :: seq_cst Y, alors X précède Y dans S.
atexit()
dans un thread et exit()
dans un autre, il ne suffit pas que les initialiseurs portent uniquement une dépendance basée sur la consommation uniquement parce que les résultats diffèrent de if a exit()
été invoqué par le même thread. Une de mes réponses les plus anciennes concernait cette différence.
exit()
. N'importe quel thread peut tuer l'intégralité du programme en quittant, ou le thread principal peut quitter en return
-ing. Cela entraîne l'appel des atexit()
gestionnaires et la mort de tous les threads quoi qu'ils fassent.
seq_cst
, dans Atomics 31.4 Ordre et cohérence: 4 . Ce n'est pas dans la norme C ++ 17 n4659 , où 32.4 - 3 définit l'existence d'un seul ordre total d'opérations seq_cst cohérent avec l'ordre «se produit avant» et les ordres de modification pour tous les emplacements affectés ; le «fortement» a été ajouté dans un projet ultérieur.