Fałszywe wyjaśnienie budzenia brzmi jak błąd, którego nie warto naprawiać, prawda?

30

Według artykułu w Wikipedii na temat Spurious Wakeups

„wątek może zostać przebudzony ze stanu oczekiwania, mimo że żaden wątek nie zasygnalizował zmiennej warunku”.

Chociaż wiem o tej „funkcji”, nigdy nie wiedziałem, co ją spowodowało, aż w tym samym artykule

„Nieprawidłowe wybudzanie może wydawać się dziwne, ale w niektórych systemach wieloprocesorowych, całkowicie budzące przewidywalność wybudzanie stanu może znacznie spowolnić wszystkie operacje zmiennych warunków”.

Brzmi jak błąd, którego nie warto naprawiać, prawda?

James
źródło
1
powiązane: „Dlaczego pthread_cond_wait ma fałszywe budzenia?”, stackoverflow.com/questions/8594591/…
Florian Castellane

Odpowiedzi:

39

TL; DR Założenie („kontrakt”) fałszywych pobudek to rozsądna decyzja architektoniczna podjęta w celu umożliwienia realistycznie solidnych implementacji narzędzia do usuwania wątków.

„Względy wydajnościowe” są tutaj nieistotne, są to tylko nieporozumienia, które stały się powszechne z powodu stwierdzenia w opublikowanym autorytatywnym odnośniku. (wiarygodne referencje mogą zawierać błędy, wiesz - po prostu zapytaj Galileo Galilei ) Artykuł w Wikipedii przechowuje odniesienie do cytowanej przez ciebie notatki tylko dlatego, że idealnie pasuje do ich formalnych wytycznych cytowania opublikowanej referencji.

O wiele bardziej przekonujący powód wprowadzenia koncepcji fałszywych pobudek podano w tej odpowiedzi na stronie SO, która jest oparta na dodatkowych szczegółach podanych w (starszej wersji) tego samego artykułu:

Artykuł w Wikipedii na temat fałszywych pobudek ma ten smakołyk:

pthread_cond_wait()Funkcja w systemie Linux jest realizowany za pomocą futexwywołania systemowego. Każde blokujące wywołanie systemowe w systemie Linux nagle wraca, EINTRgdy proces odbierze sygnał. ... pthread_cond_wait()nie może zrestartować oczekiwania, ponieważ może przeoczyć prawdziwe budzenie w krótkim czasie, gdy znajdowało się poza futexwywołaniem systemowym ...

Pomyśl tylko o tym ... jak w każdym kodzie, harmonogram wątków może chwilowo zaniknąć z powodu czegoś nienormalnego w sprzęcie / oprogramowaniu. Oczywiście, należy zachować ostrożność, aby tak się stało tak rzadkie, jak to możliwe, ale ponieważ nie ma czegoś takiego jak 100% stabilne oprogramowanie uzasadnione jest założenie, to może zdarzyć się i dbać o wdzięcznym odzysku w przypadku, gdy planista wykryje ten (np obserwując brakujące bicie serca ).

W jaki sposób program planujący mógł się zregenerować, biorąc pod uwagę, że podczas awarii zasilania może brakować niektórych sygnałów, które mają powiadamiać oczekujące wątki? Jeśli program planujący nic nie zrobi, wspomniane wątki „pechowe” po prostu się zawieszą i będą czekać wiecznie - aby tego uniknąć, program po prostu wyśle ​​sygnał do wszystkich oczekujących wątków.

Dlatego konieczne jest zawarcie „umowy”, że oczekujący wątek może zostać powiadomiony bez powodu. Mówiąc ściślej, istniałby powód - zaciemnienie programu planującego - ale ponieważ wątek został zaprojektowany (z dobrego powodu) tak, aby był nieświadomy wewnętrznych szczegółów implementacji programu planującego, powód ten prawdopodobnie lepiej przedstawić jako „fałszywy”.


Z perspektywy wątku przypomina to nieco prawo Postela (inaczej zasada solidności ),

bądźcie konserwatywni w tym, co robicie, bądźcie liberalni w tym, co akceptujecie od innych

Założenie fałszywych pobudek zmusza wątek do zachowania konserwatywności w tym, co robi : ustaw warunek przy powiadamianiu innych wątków i liberalny w tym, co akceptuje : sprawdź warunek przy każdym powrocie z oczekiwania i powtórz czekanie, jeśli jeszcze go nie ma.

komar
źródło
10
Ugh ... Prawo Postela ... powód, dla którego HTML i wszelkiego rodzaju technologie internetowe wrzucają w to tyle bzdur (np. Akceptacja HTML nieprawidłowego zagnieżdżania znaczników). Poza tym dobra odpowiedź.
Thomas Eding
3
Prawo Postela jest powodem, dla którego wiele błędów nie jest wykrywanych przez lata, ponieważ hej, nawet jeśli funkcja zwraca nieprawidłowy wynik, aplikacja nadal działa! Najlepszy wynalazek w historii.
Pacerier
2
@Pacerier: funkcja zwracająca nieprawidłowe dane wyjściowe nie jest zgodna z prawem Postela (część konserwatywna).
YvesgereY
@Pacerier: OTOH, wymaganie od innych komponentów ścisłości, aby błędy mogły zostać wykryte wcześniej, jest interesującą pozycją, błędną ze względu na zasadę „Fast Fast” i konstrukcję opartą na kontraktach.
YvesgereY
1

Nie warto tego poprawiać, ponieważ kod dzwoniącego powinien i tak korzystać z tego samego traktowania (sprawdzania stanu), aby poradzić sobie z warunkami wyścigu.

Jeden zabieg na dwa zagadnienia, które podsumowuję następująco:

Fałszywy pobudka: oczekiwanie na wątek jest zaplanowane przed ustaleniem warunku.
Wymuszone zaspanie: oczekiwanie na wątek jest zaplanowane po ponownym sfałszowaniu warunku.

Ponieważ może się to zdarzyć później, niektórzy posunęli się do wprowadzenia fałszywego wznowienia w umowie:

  • do egzekwowania dobrych praktyk poprzez wymaganie pętli predykatów.
  • dać trochę swobody implementacji harmonogramu (w tym opcji odzyskiwania awaryjnego, jak wskazał @gnat).

Referencja SO

YvesgereY
źródło
Chciałbym dać +1, ale za pomysł, że ktoś celowo wprowadził fałszywe budzenie w celu nakłonienia dzwoniących do dodania pętli predykatów w celu rozwiązania wymuszonych przespań. Uważam to za niepojęte.
ruakh
„Chodziło o wymuszenie poprawnego / niezawodnego kodu poprzez wymaganie pętli predykatów”. Zobacz podany link.
YvesgereY