La frase "si verifica fortemente prima" viene utilizzata più volte nella bozza standard C ++.
Ad esempio: Termination [basic.start.term] / 5
Se il completamento dell'inizializzazione di un oggetto con durata dell'archiviazione statica si verifica fortemente prima di una chiamata a std :: atexit (consultare, [support.start.term]), la chiamata alla funzione passata a std :: atexit viene sequenziato prima della chiamata al distruttore per l'oggetto. Se una chiamata a std :: atexit si verifica fortemente prima del completamento dell'inizializzazione di un oggetto con durata dell'archiviazione statica, la chiamata al distruttore per l'oggetto viene messa in sequenza prima che la chiamata alla funzione venga passata a std :: atexit . Se una chiamata a std :: atexit si verifica fortemente prima di un'altra chiamata a std :: atexit, la chiamata alla funzione passata alla seconda chiamata std :: atexit viene messa in sequenza prima che la chiamata alla funzione passi alla funzione prima chiamata std :: atexit.
E definito in Data race [intro.races] / 12
Una valutazione A avviene fortemente prima di una valutazione D se
(12.1) A è sequenziato prima di D, o
(12.2) A si sincronizza con D, e sia A che D sono operazioni atomiche sequenzialmente coerenti ([atomics.order]), oppure
(12.3) ci sono valutazioni B e C tali che A viene sequenziato prima che B, B avvenga semplicemente prima di C e C sia sequenziato prima di D, oppure
(12.4) esiste una valutazione B tale che A si verifica fortemente prima di B e B si verifica fortemente prima di D.
[Nota: informalmente, se A si verifica fortemente prima di B, allora A sembra essere valutato prima di B in tutti i contesti. Succede fortemente prima di escludere le operazioni di consumo. - nota finale]
Perché è stato introdotto "fortemente accade prima"? Intuitivamente, qual è la sua differenza e relazione con "succede prima"?
Cosa significa "A sembra essere valutato prima di B in tutti i contesti" nella nota?
(Nota: la motivazione di questa domanda sono i commenti di Peter Cordes sotto questa risposta .)
Progetto di preventivo standard aggiuntivo (grazie a Peter Cordes)
Ordine e coerenza [atomics.order] / 4
Esiste un unico ordine totale S su tutte le operazioni memory_order :: seq_cst, inclusi i recinti, che soddisfa i seguenti vincoli. In primo luogo, se A e B sono operazioni memory_order :: seq_cst e A accade fortemente prima di B, allora A precede B in S. Secondo, per ogni coppia di operazioni atomiche A e B su un oggetto M, dove A è ordinato per coerenza prima di B, S deve soddisfare le seguenti quattro condizioni:
(4.1) se A e B sono entrambe operazioni memory_order :: seq_cst, allora A precede B in S; e
(4.2) se A è un'operazione memory_order :: seq_cst e B accade prima di un memory_order :: seq_cst fence Y, allora A precede Y in S; e
(4.3) se un memory_order :: seq_cst fence si verifica prima che A e B sia un'operazione memory_order :: seq_cst, allora X precede B in S; e
(4.4) se un memory_order :: seq_cst fence si verifica prima che A e B accadano prima di un memory_order :: seq_cst fence Y, allora X precede Y in S.
atexit()
in un thread e exit()
in un altro, non è sufficiente che gli inizializzatori portino solo una dipendenza basata sul consumo solo perché i risultati differiscono quindi se sono exit()
stati invocati dallo stesso thread. Una mia risposta più vecchia riguardava questa differenza.
exit()
. Qualsiasi thread può uccidere l'intero programma uscendo, oppure il thread principale può uscire da return
-ing. Il risultato è la chiamata dei atexit()
gestori e la morte di tutti i thread qualunque cosa stessero facendo.
seq_cst
, in Atomics 31.4 Ordine e coerenza: 4 . Questo non è nello standard C ++ 17 n4659 , in cui 32.4 - 3 definisce l'esistenza di un singolo ordine totale di operazioni seq_cst coerenti con l'ordine "succede prima" e gli ordini di modifica per tutte le località interessate ; il "fortemente" è stato aggiunto in una bozza successiva.