2012-06-06 14 views
5

Czy ktoś może mi wyjaśnić, dlaczego potrzebujemy zagnieżdżonego blokowania?Zagnieżdżone niezrozumienie blokowania w języku C#?

spojrzenie na ten przykład:

lock (locker) 
    lock (locker) 
    lock (locker) 
     { 
     ... 
     } 

enter image description here

może ktoś proszę wyjaśnić (+ przykład będzie bardzo doceniane).

+0

masz na myśli, że zamek jest sprawdzany na tym samym obiekcie za każdym razem lub na różnych obiektach? – Nathan

+0

@Nathan same obj. –

+0

Powiązane: http://stackoverflow.com/questions/12013089/when-would-you-ever-use-nested-locking –

Odpowiedz

13

Czy ktoś może mi wyjaśnić, dlaczego potrzebujemy zagnieżdżonego blokowania?

Jest tylko problem, bo może masz zagnieżdżone (np wzajemnie rekurencyjne) zwraca się do metod, które wymagają, aby zablokować. Te metody muszą umożliwiać wywoływanie z zasobem już zablokowanym, ale nie mogą na nim polegać. Tak więc blokowanie zagnieżdżone to dozwolone, a nie potrzebne.

Kod, który wysłałeś (i książka, do której się odwołujesz) pokazuje, jak działa, redukując go do wbudowanego scenariusza. To nie jest "prawdziwy" kod.

Prosta zasada jest taka, że ​​wątek, który już jest właścicielem blokady, może ją ponownie zablokować, a liczba wyjść musi być zgodna z liczbą wejść, aby zwolnić blokadę.

+0

im czytanie zajmie się wątków. i jest tam oddzielny rozdział, którego nie rozumiem i dlatego pytam. http://books.google.co.il/books?id=VENrFSQFco8C&pg=PA813&lpg=PA813&dq=%22A+thread+can+odkreślony+kolej+trzy+obiektu+w+na+nested+(reentrant)+fashion% 22 i źródło = Bl OTS = 3uU4rnd_9P i porządek = 5NNh4Jbi7pVEZrLydrrs_bOhsBc & hl = pl & sa = X & ei = qQbPT5zGNorV8gP0q424DA & at = 0CC0Q6AEwAQ # v = onepage & Q =% 22A% 20thread% 20can% 20repeatedly% 20lock% 20the% 20same% 20object% 20in% 20a% 20nested% 20 (wklęsłego)% 20fashion% 22 & f = false –

+0

, chyba że zagnieżdżasz różne blokady ... ale tak nie jest w przykładzie OP ... –

+3

@RoyiNamir Z książki: "Wątek * może * wielokrotnie blokuje ten sam obiekt w zagnieżdżonym (powtórnie) mody ", co oznacza, że ​​masz prawo, ale nie jest to wymagane, do wielokrotnego blokowania muteksu. – univerio

1

W ogóle nie potrzebujesz zagnieżdżonego blokowania, o czym wspominasz.

Warto jednak podkreślić, że niektóre zamki mogą być zagnieżdżone. Sprawdź klasę ReaderWriterLockSlim, gdzie wprowadzasz jako blokadę odczytu, a następnie w tym zakresie, możesz uaktualnić ją do blokady zapisu.

EDIT: Jak Royi Namir zwraca uwagę, nazywając zagnieżdżone funkcje z których każdy ma swój własny zamek będzie koncepcyjnie produkować wspomniany scenariusz, ale sposób pytanie jest postawione, wygląda na to 3 zamki są wykonane w taki sam zakres, jeden po drugim, który ma mniej sensu.

+0

http://books.google.co.il/books?id=VENrFSQFco8C&pg=PA813&lpg=PA813&dq=%22A+thread+can+odkreślony+zamknąć+w+obiekcie+w+na+nested+(reentrant)+fashion % 22 i źródło = Bl OTS = 3uU4rnd_9P i porządek = 5NNh4Jbi7pVEZrLydrrs_bOhsBc & hl = pl & sa = X & ei = qQbPT5zGNorV8gP0q424DA & at = 0CC0Q6AEwAQ # v = onepage & Q =% 22A% 20thread% 20can% 20repeatedly% 20lock% 20the% 20same% 20object% 20in% 20a% 20nested% 20 (wklęsłego)% 20fashion % 22 & f = false –

5

Istnieją sytuacje, czy umiejętność umieszczania zamków w tym samym wątku jest bardzo praktyczna.

Załóżmy, że masz klasę z wieloma metodami. Załóżmy, że chcemy mieć bardzo prosty schemat blokowania takiego:

class A 
{ 
    public void MethodOne() 
    { 
     using (locker) 
     { 
      ...body... 
     } 
    } 

    public void MethodTwo() 
    { 
     using (locker) 
     { 
      ...body... 
     } 
    } 
} 

Teraz, jeśli MethodOne rozmowy MethodTwo, to masz impasu na początku MethodTwo, jeśli nie było reentrant zdolność blokowania na monitorze . Wątek po prostu zablokowałby się przez locker.

Na szczęście ten przykład działa tylko w .NET. Szafka "wie", który wątek zablokował ją i ile razy i pozwoli (tylko) na posiadanie wątku. Licznik służy do upewnienia się, że odblokowanie z perspektywy innych oczekujących wątków dzieje się tylko przy wychodzeniu z MethodOne, a nie przy wychodzeniu z MethodTwo. Jest to więc przykład użytecznego blokowania zagnieżdżonego.

Z drugiej strony przykład wspomniany w pytaniu wydaje się pochodzić z this book. Autorzy chcieli wyjaśnić, że zagnieżdżanie w gnieździe jest możliwe w.NET, automatycznie; ale ich przykładowy kod jest wymyślny i nie ma na celu pojawiać się w czyimś kodzie, chyba że próbuje dowiedzieć się, jak działa blokowanie pod maską.

+0

dlaczego impas? –

+1

w opisanym przypadku, metoda druga będzie czekać na pierwszą metodę, aby zwolnić blokadę, ale metoda ta nie zwolniłaby blokady do momentu zakończenia metody dwa = = zakleszczenie – Nathan

+1

Doskonały przykład btw - +1 – Nathan

2

Bezpośrednia odpowiedź na twoje pytanie brzmi: ty nie potrzebujesz zagnieżdżonego blokowania. Jednak kompilator pozwala na to, aby niektóre scenariusze były łatwiejsze do kodowania.

W przykładowym kodzie z pytaniem wewnętrzne zamki będą zawsze zawsze udane - ponieważ aby dostać się do wewnętrznego zamka, musisz już uzyskać zewnętrzny zamek. Twój wątek ma już blokadę na locker, więc wewnętrzna blokada "automatycznie" się powiedzie.

To nigdy nie jest konieczne i nie zapewnia dodatkowego bezpieczeństwa wątku.

Jednak w scenariuszach takich, jak te zamieszczone w odpowiedzi Jirki Hanika, zachowanie to oznacza, że ​​jeden bezpieczny w wątku element może zostać wywołany przez innego członka bezpiecznego dla wątków bez martwienia się o zakleszczenia.