2013-01-31 12 views
23

Powiedzmy, że mamy dwa wątki, jeden czyta bool w pętli, a drugi może go przełączać w określonych momentach. Osobiście myślę, że to powinno być atomowe, ponieważ sizeof(bool) w C++ to 1 bajt i nie czytasz/zapisujesz bajtów częściowo, ale chcę być w 100% pewny.Czy operacja odczytu/zapisu bool może być niepodzielona na x86?

Tak tak czy nie?

EDIT:

także w przyszłości, czy to samo dotyczy int?

+0

Czy jest to mniej niż rozmiar słowa architektury bazowej, zarówno * atomowej *, jak i * mniej wydajnej * niż to możliwe? –

+0

http://stackoverflow.com/questions/8037289/is-mutex-required-for-1-byte-shared-memory sugeruje, że jest nieatomowa. –

+0

http://stackoverflow.com/questions/8517969/is-this-correct-way-toatomically-read-and-write-a-bool sugeruje, że jest atomowy "w większości maszyn". –

Odpowiedz

14

Wszystko zależy od tego, co faktycznie masz na myśli przez słowo "atomowy".

Czy masz na myśli "ostateczna wartość zostanie zaktualizowana za jednym zamachem" (tak, na x86, który jest z pewnością gwarantowany dla wartości bajtowej - i każdej poprawnie wyrównanej wartości do co najmniej 64 bitów), lub "jeśli ustawię to do true (lub false), żaden inny wątek nie odczyta innej wartości po jej ustawieniu "(to nie jest aż tak pewne - potrzebujesz prefiksu" lock ", aby to zagwarantować).

+0

"jeśli ustawię to na true (lub false), żaden inny wątek nie odczyta innej wartości po ustawieniu go". Myślę, że pytanie jest całkiem jasne. Ta ostatnia interpretacja nie ma nic wspólnego z atomowością. – jberryman

+2

@jberryman: Problem dotyczy zarówno pamięci podręcznych, jak i kompilatora optymalizującego odczyt pamięci. W niektórych wątkach 'b = false;' nie gwarantuje, że wszystkie inne wątki, w ich następnym przypadku 'if (b) ...', wykryją, że 'b' jest fałszywe. Wymaga to, aby kompilator nie zoptymalizował dostępu do 'b' do' tmp = b; ... if (tmp) ... '[gdzie' tmp' jest rejestrem]. W zależności od kodu wewnątrz wątku zdarzają się sytuacje, gdy kompilator zrobi to. –

6

Tylko x86 gwarantuje wyrównywanie tekstu do odczytów i zapisów o rozmiarze słowa. Nie gwarantuje on żadnych innych operacji, chyba że jest wyraźnie atomowy. Dodatkowo, musisz przekonać swój kompilator do wydania odpowiednich odczytów i zapisów w pierwszej kolejności.

52

Istnieją trzy odrębne kwestie, które „atomowe” typów w C++ 11 adres:

  1. łzawienie: odczytu lub zapisu obejmuje wiele cykli magistrali, oraz przełącznik wątek pojawia się w trakcie operacji ; może to spowodować nieprawidłowe wartości.

  2. koherencja pamięci podręcznej: zapis z jednego wątku aktualizuje pamięć podręczną procesora, ale nie aktualizuje pamięci globalnej; odczyt z innego wątku odczytuje pamięć globalną i nie widzi zaktualizowanej wartości w pamięci podręcznej drugiego procesora.

  3. optymalizacja kompilatora: kompilator tasuje kolejność odczytywania i zapisywania przy założeniu, że wartości nie są dostępne z innego wątku, co powoduje chaos.

Użycie std::atomic<bool> zapewnia prawidłowe zarządzanie wszystkimi trzema z tych problemów. Nie używasz std::atomic<bool> pozostawia Cię w zgadywaniu, z najlepszym, nieprzenośnym kodem.

Powiązane problemy