sobota, 1 marca 2014

lock (s_obj)
{
   // sekcja krytyczna
}

w rzeczywistości, po skompilowaniu to:

try
{
   Monitor.Enter(s_obj);/
   // sekcja krytyczna
}

finally
{
   Monitor.Exit(s_obj);
}

Wzorzec ten ma kilka małych wad:
  1. Jeśli wystąpi wyjątek w sekcji krytycznej wówczas trafiamy do finally i zwalniamy zasób. Skoro powstał wyjątek, to możemy nie chcieć zwalniać sekcji krytycznej. Może lepszy byłby deadlock niż dalsze niszczenie danych przez wpuszczenie innego wątku.
  2. Jeśli wyjątek poleci w metodzie Monitor.Enter wówczas trafiamy do finally i wywołujemy metodę Monitor.Exit co powoduje kolejny wyjątek.
  3. Konstrukcja ta nie jest odporna na zakleszczenia. W szczególnych przypadkach wolelibyśmy sprawdzać czas jaki dany wątek oczekuje na wejście do sekcji krytycznej i po przekroczeniu tego czasu odpuszcza sobie dalsze czekanie.
Rozwiązaniem problemów opisanych w punkcie 2 oraz 3 jest kod:

bool token = false;
try
{
   Monitor.TryEnter(s_obj, new TimeSpan(0, 0, 0, 5), ref token);
}
finally
{
   if(token)
      Monitor.Exit(s_obj);
}
Categories: ,

0 komentarze :

Prześlij komentarz