2010-06-29 20 views
10

W wielu dokumentach MSDN jest to napisane pod nagłówkiem Bezpieczeństwo wątków;msdn: Co to jest "Bezpieczeństwo wątków"?

"Dowolne publiczne statyczne (Shared in Visual Basic) elementy tego typu są bezpieczne dla wątków. Żadne elementy instancji nie mają gwarancji, że są bezpieczne dla wątków."

na przykład; here

Czy ktoś może to wyjaśnić w dość prosty sposób? Dziękuję :)

Odpowiedz

11

Eric Lippert ma znakomitą blog post na ten temat. Zasadniczo jest to trochę bezsensowne samo w sobie.

Osobiście nie ufam zbytnio MSDN z przodu, gdy widzę tę płytę kotła. Nie zawsze oznacza to, co mówi. Na przykład, mówi to samo o Encoding - pomimo faktu, że wszyscy używamy kodowania z wielu wątków w każdym miejscu.

O ile nie ma powodu sądzić, że jest inaczej (co robię z Encoding) zakładam, że mogę wywołać dowolnego statycznego członka z dowolnego wątku bez korupcji stanu globalnego. Jeśli chcę użyć instancji członków tego samego obiektu z różnych wątków, zakładam, że to w porządku, jeśli zapewniam - przez blokowanie - że tylko jeden wątek będzie używać obiektu na raz. (Oczywiście nie zawsze tak jest.) Niektóre obiekty mają powinowactwo gwintu i aktywnie nie lubią być używane z wielu wątków, nawet z blokowaniem w miejscu. Przykładami są tutaj kontrolki interfejsu użytkownika.)

Oczywiście, staje się to trudne jeśli obiekty są udostępniane w sposób nieoczywisty - jeśli mam dwa obiekty, z których każdy ma odniesienie do trzeciego, to mogę w końcu użyć dwóch pierwszych obiektów niezależnie od różnych wątków, z właściwym blokowaniem - ale nadal w końcu uszkodzić trzeci obiekt .

Jeśli typ powoduje, że reklamuje się jako bezpieczny dla wątków, mam nadzieję, że poda szczegóły na jego temat.To proste, jeśli jest niezmienne - możesz po prostu użyć instancji, które ci się podobają, bez martwienia się o nie. Są to typy częściowo lub całkowicie "wątkowe", które są zmienne, gdy szczegóły mają duże znaczenie.

+3

Co oznacza mała notatka MS, brzmi: "Nie zrobiliśmy wiele/żadnych blokad w metodach instancji [prawdopodobnie ze względu na wydajność], więc jeśli przejdziecie i sic tuzin wątków na tym, a to zabrzmi, nie" Przychodzą do nas płaczące, to nie jest błąd i ostrzegaliśmy cię. – cHao

+1

@CHao: Jest dużo * więcej, aby uzyskać wielowątkowość w prawo niż po prostu zablokować metody instancji. Często chcesz, aby cała * seria * wywołań metodowych działała atomowo - w takim przypadku nie pomoże żadna ilość wewnętrznego blokowania. Iterowanie poprzez kolekcję jest oczywistym przykładem. –

+0

@Jon: Zgoda, jest o wiele więcej. Ale nie ma o wiele więcej, czego można by się spodziewać po SM, ponieważ wbudowana atomowość w wielu wywołaniach metod nie ma nawet sensu od każdego, kto ceni sobie stabilność. (Wymagałoby to dokumentów API, które mówią takie rzeczy jak "Jeśli wywołasz IsEmpty(), i zwraca false, musisz zadzwonić Remove() lub ReleaseLock(), aby uniknąć zakleszczenia".) A nawet w jednej metodzie, może to spowodować problemy z wydajnością, jeśli są używane niepotrzebnie. Więc stwardnienie rozsiane słusznie nie zawracało sobie głowy. To mój punkt. – cHao

5

Możesz uzyskać dostęp do wszystkich publicznych statycznych elementów tej klasy z wielu wątków w tym samym czasie, bez zakłócania stanu klasy. Jeśli wiele wątków spróbuje uzyskać dostęp do obiektu za pomocą metod instancji (nie oznaczonych jako "statyczne") w tym samym czasie, obiekt może zostać uszkodzony.

Klasa jest "bezpieczna dla wątków", jeśli próba dostępu do tej samej instancji klasy z wielu wątków w tym samym czasie powoduje problemy z , a nie.

4

Obiekt będący "bezpieczny dla wątków" oznacza, że ​​jeśli dwa wątki używają go w (lub bardzo blisko, w systemach jednoprocesorowych) dokładnie w tym samym czasie, nie ma szans, że zostanie on uszkodzony przez wspomniany dostęp. Zwykle osiąga się to przez pozyskiwanie i zwalnianie blokad, które mogą powodować wąskie gardła, więc "wątek bezpieczny" może również oznaczać "powolny", jeśli jest wykonywany, gdy nie musi być.

członkowie statyczne publiczne są dość dużo oczekiwać, aby być dzielone pomiędzy wątkami (Uwaga, VB nawet rozmowy to „wspólna”), tak statyka publiczne są zazwyczaj wykonane w taki sposób, że mogą być używane bezpiecznie.

Członkowie instancji nie są zazwyczaj wątkowo bezpieczni, ponieważ w ogólnym przypadku spowolniłoby to działanie. Jeśli masz obiekt, który chcesz udostępnić między wątkami, musisz więc zrobić własną synchronizację/zablokowanie.

0

Aby to zrozumieć, rozważ następujący przykład. W MSDN opis klasy .net HashSet jest część, która mówi o bezpieczeństwie wątku. W przypadku klasy HashSet, MSDN mówi: "Wszelkie publiczne statyczne (Shared in Visual Basic) elementy tego typu są bezpieczne dla wątków. Każdy członek instancji nie może zagwarantować bezpieczeństwa w wątku. " Ponieważ wszyscy znamy pojęcie warunków wyścigu i zakleszczenia, ale co Microsoft chce powiedzieć po prostym angielskim? Jeśli dwa wątki dodają dwie wartości do "instancji" HashSet, to jest jakaś sytuacja, w której możemy uzyskać jej licznik jako jeden. Przyczyna w tej sytuacji powoduje, że obiekt HashSet jest uszkodzony, ponieważ mamy teraz dwa obiekty w HashSet, ale jego liczba pokazuje tylko jeden. Jednak publiczna statyczna wersja HashSet nigdy nie stanie przed takim zepsuciem, nawet jeśli dwa wątki jednocześnie dodają wartości.