2011-08-02 25 views
42

Widziałem TVar jest prosty pojemnik, a TMVar jest taki sam jak MVar, co oznacza, że ​​ma zamek itp., Ale w monadę STM. Zastanawiam się, dlaczego byłoby to konieczne, ponieważ idea STM polega na tym, aby zamki były niepotrzebne.Różnica między TVar i TMVar

Który z nich należy użyć, jeśli, na przykład, masz typ, taki jak [Handle], listę uchwytów gniazd, których chcesz użyć między wątkami utworzonymi przez forkIO?

Odpowiedz

38

to naprawdę nie jest to kwestia blokowania, chodzi o to, co oznacza odniesienie:

  • TVar jest zmienny odniesienia w STM, reprezentujący ogólny stan współdzielonej. Tworzysz go z wartością, możesz go czytać i pisać itd. Jest bardzo podobny do IORef lub STRef (które i tak są takie same).

  • TMVar to odnośnik do gniazda, którego wątki mogą używać do komunikacji. Można go utworzyć, trzymając wartość lub pustą. Możesz umieścić w nim wartość, która, jeśli jest już wypełniona blokami, dopóki ktoś jej nie opróżni; lub możesz wziąć z niego wartość, która jeśli już jest pusta, dopóki ktoś jej nie zapełni. Jest on oczywiście zbliżony do MVar, ale w przypadku wielu typowych zastosowań może być prostsze myślenie o nim jako o pojedynczym elemencie kolejki stosowanym do komunikacji między producentem a konsumentem.

W skrócie, TVar jest ogólny stan wspólne, użyj go, jeśli chcesz dostawać atomowych danych z dowolnych miejscach. TMVar jest prymitywem synchronizacji, użyj go, jeśli chcesz, aby wątek czekał, aż coś stanie się dostępne, a inny zaczeka, aż coś będzie potrzebne.

Należy również pamiętać TChan, który jest realizowany w przybliżeniu jako dwie TVar s trzymające lokalizacje w połączonej listy gdzie każdy link do przodu jest również TVar i działa jako nieograniczonej kolejce do komunikacji.

Wszystkie te mogą być używane w nieco inny sposób, oczywiście - można zerknąć na wartość TMVar bez usuwania go, na przykład, jeśli chcesz scenariusz, w którym wiele wątków czeka na pojedynczy zasób stają się dostępne, ale nigdy nie są "zużyte". zdecydowanie nie porównywalny do różnic między IORef i MVar -

19

Różnice między TVar i TMVar nie są tak duże, jak wyglądają.

Podczas gdy MVar rzeczywiście zapewnia pewne blokowanie dla bezpieczeństwa gwintów, TMVar nie robi nic ciekawego! (bez dodatkowego blokowania) Wszystko co ważne jest już zaimplementowane z STM i TVar, więc TMVar a jest tylko skrótem dla TVar (Maybe a) wyposażonym w kilka fajnych funkcji (niektóre z nich blokują za pomocą funkcji retry).

Czy blokowanie z retry jest kompatybilne z duchem STM i czy eliminuje niektóre zalety STM (brak zakleszczeń itp.) To osobne pytanie i chciałbym zobaczyć kogoś bardziej doświadczonego, aby na nie odpowiedzieć.

+1

W jaki sposób "ponowienie" spowodowałoby zakleszczenia?Wycofuje bieżącą transakcję, a następnie blokuje, aż sytuacja zmieni się w jakiś sposób. Nie blokuje (w rzeczywistości nie może) transakcji. –

+6

Mimo że w środku transakcji nie nastąpi zakleszczenie, można utworzyć transakcje, które nigdy nie powiodą się w sposób podobny do klasycznych zakleszczeń, takich jak dwie transakcje oczekujące na wyniki drugiej strony. Nie jest od razu oczywiste, jak to się różni od impasu w praktyce. – Rotsor

+4

Ah, racja. Uważam, że właściwym terminem jest, odpowiednio, "livelock". Jest to raczej rodzaj głodu zasobów, niż jest jak impas. Podczas gdy impasy mogą łatwo wyniknąć z niepowiązanych zastosowań tych samych zasobów, uważam, że optymistyczny charakter STM sprawia, że ​​locklocki są mało prawdopodobne, chyba że istnieje bezpośredni konflikt lub bardzo wysoki ogólny spór. –