2009-06-26 7 views
9

Mam debugowanie problemu zakleszczenia, a stos wywołań pokazuje, że wątki oczekują na niektóre zdarzenia.Liczba ujemnych blokad sekcji krytycznej

Kod używa sekcji krytycznej jako prymitywu synchronizacji. Myślę, że jest tu pewien problem. Również debugger wskazuje na sekcję krytyczną, która jest własnością innego wątku, ale liczba blokad wynosi -2. Zgodnie z moim rozumieniem liczba blokad> 0 oznacza, że ​​sekcja krytyczna jest zablokowana przez co najmniej jeden wątek.

Czy istnieje jakakolwiek możliwość, że patrzę na odpowiednią sekcję krytyczną, która może być przyczyną impasu.

W jakich sytuacjach krytyczna sekcja może mieć ujemną liczbę blokad?

+0

Raymond Chen napisał właśnie post o konsekwencjach pozostawiania CS więcej razy niż wchodzenie do niego. I pierwsze trzy komentarze są warte przeczytania ... http://blogs.msdn.com/oldnewthing/archive/2009/06/19/9777996.aspx – eran

Odpowiedz

5

Zakładam, że mówimy o klasie CCriticalSection w MFC. Myślę, że patrzysz na odpowiednią sekcję krytyczną. Zauważyłem, że liczba blokad sekcji krytycznej może być ujemna, jeśli liczba wywołań funkcji Lock() jest mniejsza niż liczba połączeń Unlock(). Zauważyłem, że zazwyczaj dzieje się to w następującym kodzie:

void f() 
{ 
    CSingleLock lock(&m_synchronizer, TRUE); 
    //Some logic here 
    m_synchronizer.Unlock(); 
} 

Na pierwszy rzut oka ten kod wygląda całkowicie bezpiecznie. Należy jednak zauważyć, że używam metody Unlock() metody CCriticalSection bezpośrednio zamiast metody Unlock() programu CSingleLock. Teraz, gdy funkcja się kończy, CSingleLock w swoim destruktorze ponownie wywołuje Unlock() sekcji krytycznej, a jej liczba blokująca staje się ujemna. Po tym aplikacja będzie w złym stanie i zaczną się dziać dziwne rzeczy. Jeśli używasz krytycznych sekcji MFC, sprawdź, czy nie występują tego typu problemy.

+0

LockCount zależy od wersji systemu Windows, którego używasz: http : //msdn.microsoft.com/en-us/library/ff541979.aspx – hfrmobile

23

Uwaga: od wersji Windows Server 2003 (dla klienta OS this is Vista and newer) znaczenie LockCount zmieniło się, a -2 jest wartością całkowicie normalną, powszechnie widoczną, gdy wątek wszedł do sekcji krytycznej bez czekania i żaden inny wątek nie czeka CS. Zobacz Displaying a Critical Section:

W systemie Microsoft Windows Server 2003 z dodatkiem Service Pack 1 i nowszych wersjach systemu Windows, w polu licznika blokad jest analizowany w następujący sposób:

  • Najniższy bit pokazuje stan blokady. Jeśli ten bit ma wartość 0, sekcja krytyczna jest zablokowana; jeśli jest 1, sekcja krytyczna nie jest zablokowana.
  • Następny bit pokazuje, czy wątek został obudzony dla tej blokady. Jeśli ten bit ma wartość 0, to obudzono wątek dla tego zamka; jeśli jest 1, żaden wątek nie został wybudzony.
  • Pozostałe bity są jedynymi uzupełnieniami liczby wątków oczekujących na blokadę.
+3

Wspaniałe informacje, których nie widziałem gdzie indziej. Pomógł mi rozwiązać pewne dziwne zachowanie części krytycznych. –

+2

Ditto to @ mistiano's comment. Nie wiedziałem, że Microsoft zmienił sposób, w jaki LockCount działa na Server 2003 i nowszych wersjach. Link był BARDZO przydatny! –