2009-09-01 14 views

Odpowiedz

8

Nie mogę mówić konkretnie o Clojure, ale ... oznacza to, że nie musisz czekać, aż ktoś coś zrobi zanim zaczniesz pracować. Który jest świetny.

Zazwyczaj osiąga się to w przypadku typów niezmiennych. Jeśli nic nie można zmienić, nie musisz czekać, aż ktoś zrobi to, zanim będziesz mógł uzyskać do niego dostęp.

+2

Kim jest "ktoś"? Czy mógłbyś podać przykład? Nie sądzę, żeby istniała jakakolwiek "osoba, która dzieli się moimi przedmiotami ze mną. Może powinienem sprawdzić pod łóżkiem. –

+4

* ktoś * jest po prostu kolejnym kawałkiem kodu, w innym wątku, uzyskującym dostęp do tego obiektu. –

+0

Czasami jest szybsze, czasami wolniej - jak większość optymalizacji, które są wykonywane bez pomiaru. Czasami to dobrze, a czasami te zamki byłyby lepsze. Dlatego nazywamy nas inżynierami oprogramowania **. – Eloff

5

Zakleszczenia. A może bardziej poprawny jest ich brak.

Jednym z największych problemów w większości języków jest to, że możesz skończyć z impasu, które:

  1. piekło na ziemi do debugowania.
  2. Trudno się upewnić, że się pozbyłeś.

Teraz bez zamków, oczywiście nie wpadniesz w zakleszczenia.

+0

Nigdy nie spotkałem się z impasem, o którym wiedziałem. Czy zdarza się to częściej, niż zdaje sobie z tego sprawę? Sądzę, że po prostu nie znam tego problemu, mimo że dużo zaprogramowałem. Jedyne problemy z blokowaniem, o których wiedziałem, były w bazie danych. –

+0

@ i_like_monkeys Jeśli piszesz stronę WWW w języku C#, większość problemów związanych z blokowaniem będzie w niższych warstwach (serwer internetowy i baza danych), ale jeśli zamierzasz opracować programy, które zdecydowanie stanowią problem. – tomjen

+0

Jeśli masz zakleszczenie, objawem będzie zazwyczaj zawieszenie się twojego programu (0% użycia procesora, żadne z zadań nie zostanie wykonane, nigdy, dopóki nie zabijesz go ręcznie za pomocą Menedżera zadań lub itd.). Zakleszczenia mogą wystąpić, jeśli twoje nici trzymają więcej niż jedną blokadę na raz, a różne wątki przejmują zamki w innej kolejności. –

1

Zaletą współbieżności bez blokady jest brak złożoności programu. W językach imperatywnych programowanie współbieżne opiera się na blokadach, a gdy program staje się jeszcze bardziej złożony, trudne do naprawienia błędy robactwa wkradają się.

+0

Czy zdarzyło Ci się to kiedykolwiek? –

9

Współdziałanie bez blokady zapewnia także niezłą korzyść, że czytniki nigdy nie muszą czekać na innych czytników . Jest to szczególnie przydatne, gdy wiele wątków będzie odczytywać dane z jednego źródła. Nadal musisz zdefiniować zależności danych w swoim programie i jawnie zdefiniować części transakcji, które można bezpiecznie przenieść.
STM chroni przed zakleszczeniami i prawie wszystkimi wystąpieniami mechanizmu LiveLock, chociaż nie chroni przed niepowodzeniami współbieżności, nadal można tworzyć przypadki, w których transakcja zakończy się niepowodzeniem, ponieważ brakuje jej zasobów do zachowania historii, ale ważną częścią jest to, że niepowodzenie współbieżności uzyskało będzie jawny i będziesz mógł odzyskać od nich

+0

Tak! STM = Software Transactional Memory. To dobra robota do sprawdzenia, jeśli chcesz dowiedzieć się więcej o tym, jak to działa. –

+2

w Clojure STM, czytelnicy nie muszą nawet czekać na innych pisarzy (chyba, że ​​chcą zrobić transakcyjny odczyt, aby uzyskać spójną migawkę w wielu odsyłaczach). – mikera

+0

"Czytelnicy nigdy nie muszą czekać na innych czytelników" W imperatywnym świecie, Zamki do odczytu i zapisu zapewniają tę funkcjonalność :) – vemv

2

Dopóki będziesz pisać programy ściśle sekwencyjne (wykonaj A, następnie B, a następnie C; zakończone!) nie masz problemów z współbieżnością, a mechanizmy współbieżności języka pozostają nieistotne .

Po przejściu z programów "programowanie ćwiczeń" do rzeczy rzeczywistych, dość szybko napotkasz problemy, których rozwiązaniem jest wielowątkowość (lub jakikolwiek aromat współbieżności, który masz dostępny).

Przypadek: Programy z GUI. Załóżmy, że piszesz edytor z sprawdzaniem pisowni. Chcesz, aby moduł sprawdzania pisowni działał cicho w tle, ale chcesz, aby interfejs graficzny płynnie akceptował dane wprowadzane przez użytkownika. Więc uruchamiasz te dwie czynności jako oddzielne wątki.

Przypadek: Ostatnio napisałem program (do pracy), który zbiera statystyki z dwóch plików dziennika i zapisuje je w bazie danych. Każdy plik trwa około 3 minut. Przeniosłem te procesy na dwa wątki, które biegną obok siebie, skracając całkowity czas przetwarzania z 6 minut do nieco ponad 3.

Przypadek: oprogramowanie do symulacji naukowej/inżynierskiej. Istnieje wiele problemów, które rozwiązuje się, obliczając pewien efekt (na przykład przepływ ciepła) w każdym punkcie trójwymiarowej siatki reprezentującej badany obiekt (jądro gwiazdy, wybuch jądrowy, rozproszenie geograficzne populacji owadów ...). Zasadniczo to samo obliczenie jest wykonywane w każdym punkcie i przy wielu punktach, więc rozsądnie jest je wykonywać równolegle.

We wszystkich tych przypadkach i wielu innych, ilekroć dwa procesy obliczeniowe uzyskują dostęp do tej samej pamięci (= zmiennych, jeśli chcesz) mniej więcej w tym samym czasie, istnieje możliwość ich wzajemnego zakłócania i zakłócania pracy nawzajem. Ogromna gałąź informatyki, która zajmuje się "programowaniem współbieżnym", zajmuje się pomysłami, jak rozwiązać ten problem.

Dogodnie przydatną dyskusję rozpoczynającą ten temat można znaleźć pod adresem in Wikipedia.

0

Taka "bezkontraktowa współbieżność" nie jest tak naprawdę cechą języka języka; jest raczej cechą platformy lub środowiska uruchomieniowego, a biada językiem, który nie zejdzie z drogi, aby dać ci dostęp do tych obiektów.

Myślenie o transakcjach między współdziałającą blokadą i bez blokady jest analogiczne do problemu meta-kostkowego ewaluatora: można wdrożyć blokady w kategoriach operacji atomowych (np. Porównać-i-zamienić lub CAS) i można wdrożyć operacje atomowe pod względem zamków. Które powinno być na dole?

5

Największe znaczenie ma to, że zamki nie składają się na.

O ile pisanie kodu z prostą strategią blokowania (na przykład zsynchronizowaną klasą Java .....) jest trywialne, staje się coraz bardziej skomplikowane, gdy zaczniesz blokować wiele obiektów i zaczniesz tworzyć złożone transakcje które łączą różne zablokowane operacje. Zakleszczenia mogą wystąpić, wydajność cierpi, logika blokowania zaczyna sprawiać, że kod jest wyjątkowo zawiły i w pewnym momencie kod staje się nieosiągalny.

Problemy te staną się widoczne dla każdego, kto musi zbudować duży, złożony system współbieżny (a ich rozwiązanie było główną motywacją Richa Hickeya do stworzenia Clojure).

Drugi numer to wydajność.

Zarówno blokowanie, jak i STM wyraźnie nakładają się na siebie. Ale w niektórych ważnych przypadkach koszty ogólne STM mogą być znacznie niższe.

W szczególności współbieżność bez blokady (tak jak w przypadku Clojure STM) zwykle oznacza, że ​​czytelnikom nie przeszkadzają żadne inne wątki (w tym pisarze!), Jeśli uzyskują dostęp do danych poza transakcją. Może to być ogromna wygrana w dość powszechnym przypadku, gdy odczyty nie muszą być transakcyjne i znacznie przewyższają liczbę pisań (pomyśl o większości aplikacji internetowych ...). Nietransakcyjne odczyty referencji STM w Clojure są zasadniczo wolne od napowietrznych linii.

+0

'Odtworzenia nietransakcyjne referencji STM w Clojure są zasadniczo wolne od napowierzchni". Zasadniczo powinno to być odczytywanie transakcyjne? Doktor mówi: "Czytelnicy i osoby dojeżdżające do pracy nigdy nie będą blokować pisarzy, osób dojeżdżających do pracy czy innych czytelników". – vemv

Powiązane problemy