Wyrażenie „zdecydowanie zdarza się wcześniej” jest używane kilkakrotnie w standardowym projekcie C ++.
Na przykład: Zakończenie [basic.start.term] / 5
Jeśli zakończenie inicjalizacji obiektu o czasie przechowywania statycznym nastąpi zdecydowanie przed wywołaniem std :: atexit (patrz [support.start.term]), wywołanie funkcji przekazane do std :: atexit jest sekwencjonowany przed wywołaniem obiektu destruktora dla obiektu. Jeśli wywołanie std :: atexit wystąpi zdecydowanie przed zakończeniem inicjalizacji obiektu o statycznym czasie przechowywania, wywołanie obiektu destruktora dla obiektu jest sekwencjonowane przed wywołaniem funkcji std :: atexit . Jeśli wywołanie std :: atexit wystąpi zdecydowanie przed kolejnym wywołaniem std :: atexit, wywołanie funkcji przekazanej do drugiego wywołania std :: atexit jest sekwencjonowane przed wywołaniem funkcji pierwsze wywołanie std :: atexit.
I zdefiniowane w Wyścigi danych [intro.races] / 12
Ocena Zdecydowanie występuje przed oceną D, jeśli również
(12.1) A jest sekwencjonowane przed D, lub
(12.2) A synchronizuje się z D, a oba A i D są sekwencyjnie spójnymi operacjami atomowymi ([atomics.order]) lub
(12.3) istnieją oceny B i C takie, że A jest sekwencjonowane przed B, B po prostu dzieje się przed C, a C jest sekwencjonowane przed D, lub
(12.4) istnieje ocena B taka, że A dzieje się zdecydowanie przed B, a B występuje zdecydowanie przed D.
[Uwaga: Nieoficjalnie, jeśli A zdarza się zdecydowanie przed B, to A wydaje się być oceniane przed B we wszystkich kontekstach. Zdecydowanie dzieje się przed wykluczeniem operacji konsumpcji. - uwaga końcowa]
Dlaczego wprowadzono „zdecydowanie wcześniej”? Intuicyjnie, jaka jest jego różnica i związek z „dzieje się wcześniej”?
Co oznacza „A wydaje się być oceniane przed B we wszystkich kontekstach” w notatce?
(Uwaga: motywem tego pytania są komentarze Petera Cordesa pod tą odpowiedzią ).
Dodatkowy projekt standardowej wyceny (dzięki Peter Cordes)
Porządek i spójność [atomics.order] / 4
Istnieje jedna suma S dla wszystkich operacji memory_order :: seq_cst, w tym ogrodzeń, która spełnia następujące ograniczenia. Po pierwsze, jeśli A i B są operacjami memory_order :: seq_cst, a A zdarza się silnie przed B, to A poprzedza B w S. Po drugie, dla każdej pary operacji atomowych A i B na obiekcie M, gdzie A jest uporządkowaną spójnością przed B S musi spełnić następujące cztery warunki:
(4.1) jeśli A i B są operacjami memory_order :: seq_cst, to A poprzedza B w S; i
(4.2) jeśli A jest operacją memory_order :: seq_cst, a B dzieje się przed ogrodzeniem Y kolejki memory_order :: seq_cst, to A poprzedza Y w S; i
(4.3) jeśli ogrodzenie memory_order :: seq_cst X nastąpi przed A, a B jest operacją memory_order :: seq_cst, to X poprzedza B w S; i
(4.4) jeśli X_pamięci :: seq_cst ogrodzenie X nastąpi przed A, a B ma miejsce przed X_pamięci :: seq_cst ogrodzenie Y, to X poprzedza Y w S.
atexit()
w jednym wątku, a exit()
w drugim, inicjalizatory nie mogą przenosić tylko zależności zależnej od zużycia tylko dlatego, że wyniki różnią się od tego, czy exit()
wywołano go przez ten sam wątek. Moja starsza odpowiedź dotyczyła tej różnicy.
exit()
. Dowolny wątek może zabić cały program, wychodząc lub główny wątek może wyjść przez return
-ing. Powoduje to przywołanie przewodników atexit()
i śmierć wszystkich wątków, bez względu na to, co robią.
seq_cst
w Atomics 31.4. Porządek i spójność: 4 . Nie ma tego w standardzie C ++ 17 n4659 , w którym 32.4 - 3 definiuje istnienie pojedynczej całkowitej kolejności operacji seq_cst zgodnej z kolejnością „zamówień sprzed” i zleceniami modyfikacji dla wszystkich dotkniętych lokalizacji ; „zdecydowanie” dodano w późniejszym szkicu.