Jakie są możliwe wyniki końcowe dla zmiennej x w poniższym fragmencie C ++? (Proszę odpowiedzieć na podstawie tego, co jest dozwolone przez standard C ++, a nie, co jest obecnie dostępne na różnych platformach)

// Inside Thread 0
std::atomic<int> x = {2};
// Inside Thread 1
x.fetch_sub(1,std::memory_order_relaxed)
// Inside Thread 2
x.fetch_sub(1,std::memory_order_relaxed)

Idealnie chcę x na koniec zero. Czy to sprawa, Eventhough, używam std::memory_order_relaxed?

Edytuj: Aby dokonać pytania bardziej precyzyjne, jest to gwarantowane, że 1) w gwintach 1 i 2 Wartość zwracana jest 0 lub 1, a 2) wartość powrotowa w gwintach 1 i 2 są różne.

1
Koosha 25 grudzień 2019, 01:19

1 odpowiedź

Najlepsza odpowiedź

Krótka odpowiedź: tak.

Długa odpowiedź: std::memory_order_relaxed jest opisana jako:

Odprężona operacja: Nie ma synchronizacji ani zamawiania ograniczeń nałożonych na inne czytanie lub pisze, jest gwarantowany tylko atomowość tej operacji.

Źródło

To, co skutecznie oznacza, że gwarantuje tylko atomowość. Oznacza to, że operacja std::atomic::fetch_sub zagwarantuje tylko atomową operację odczytu odczytu, bez zamawiania w ogóle dotyczącym innych operacji. Nie oznacza to jednak, że kompilator może zmienić kolejność dwóch różnych operacji Atomic Read, Modyfikowanie i napisanie (które mogłyby prowadzić do wyścigu danych, który jest niezdefiniowany zachowanie). Są nadal atomowe .

Idealnie chcę x na koniec zero. Czy to sprawa, Eventhough, używam std::memory_order_relaxed?

Kolejność pamięci nie będzie miała znaczenie w tym przypadku. Żaden z nich nie zakłóca podstawowych gwarancji atomowości. Powyższe oświadczenie, które dokonałeś, będzie true dla dowolny porządek pamięci , ponieważ posiada to prawda, z definicji, dla dowolnej zmiennej atomowej, która jest modyfikowana w taki sposób (dwa, potencjalnie asynchroniczne, odstawianie wartości początkowej 2).

Aby sprawić, że pytanie jest bardziej precyzyjne, jest to zagwarantowane, że 1) w obu gwintach wartość zwracana jest albo 0 lub 1 i 2) wartość powrotowa w gwintach 1 i {{x3 }} są różne.

Tak i tak, zakładając, że wątki zwracają wartość, która x trzyma tuż po połączeniu fetch_sub, która jest prawdopodobnie technicznie niepoprawna (wątki nie Wartości powrotu), ale widzę, gdzie przyjeżdżasz stąd.

5
Fureeish 24 grudzień 2019, 22:50