2015-09-12 37 views
5

Jeśli spojrzysz na dokumentację opisującą użycie zmiennych warunkowych (cv), zobaczysz np. w PThreadach i C++ nie trzeba trzymać muteksu cv, aby wywołać powiadomienie na tym cv. Np. w Javie i Pythonie musisz zablokować muteks, aby zrobić to samo.Zmienny schemat użycia warunku w C/C++ i innych językach

Czy istnieje jakiś głęboki powód, dla którego rzeczy są realizowane w ten sposób (mam na myśli ten drugi przypadek), zważywszy, że implementacja języka takiego jak Java ostatecznie wykorzystuje niektóre narzędzia macierzystego wątkowania?

+0

Prawdopodobnie nie jest zaimplementowany tylko na podstawie pthreadów ... ale to tylko założenie. Czuję, że to pytanie może się polepszyć (lub nawet * dowolne *) odpowiedzi na http://cs.stackexchange.com/ ... –

+0

Oczywiście JVM może to zaimplementować w taki sposób, ale powoduje to powszechny błąd, który widziałem wiele, wiele osób robi w języku C++ znacznie mniej prawdopodobne przy rozsądnie niskim koszcie (trzeba przytrzymać blokadę nieco dłużej, ale to wszystko). – Voo

+0

@Voo Błąd polegający na tym, że muteks nie jest trzymany podczas modyfikowania danych, od których zależy warunek? – vehsakul

Odpowiedz

0

Podstawowe narzędzia synchronizacji Java notify i notifyAll wymagają synchronizacji obiektu przed wywołaniem. Jest to prosty punkt bezpieczeństwa, ponieważ wymaga on również zsynchronizowania na nim przed wait.

Na przykład, jeśli masz dwa wątki. Jeden wątek odczytuje dane z bufora, a jeden wątek zapisuje dane w buforze.

Wątek danych do odczytu musi poczekać, aż wątek danych zapisu zakończy zapisywanie bloku danych do bufora, a następnie może odczytać blok.

Jeśli wait(), notify() i notifyAll() metody można nazwać bez synchronizacji wtedy można dostać sytuacji wyścigu gdzie:

  • Gwint odczyt nazywa wait() i wątek zostanie dodany do kolejki oczekiwania.

  • W tym samym czasie, wątek zapisu wywołuje notify(), aby zasygnalizować, że dodał dane.

  • Wątek do czytania pomija zmianę i czeka na zawsze, ponieważ notify() został przetworzony przed wait().

Przez zmuszając wait i notify się zdarzyć w bloku zsynchronizowanego warunek ten wyścig jest usuwany.