Zagrożenia w wielowątkowości: Two-Step Dance

Dzisiaj o kolejnym, mało znanym, ale bardzo powszechnym zagrożeniu w środowisku współbieżnym. Zjawisko opisane w tym poście jest ściśle powiązane z lock convoy i stampede, które opisywałem w zeszłym tygodniu.

Problem jest bardzo prosty. Budzimy wątek za pomocą Pulse\Set, ale wątek i tak nic sensowego nie może zrobić, ponieważ dany zasób jest wciąż zablokowany, co skutkuje, że taki wątek znów zostanie uśpiony. Zarys:

void T1()
{
    lock (Sync)
    {
        blocker.Set();
    }
}
void T2()
{
    blocker.WaitOne();
    
    lock (Sync)
    {
    }
}

Zmienna blocker to jakakolwiek klasa implementująca WaitHandle. Skutek będzie taki, że T1 wyśle sygnał, T2 zostanie obudzony ale wtedy będzie chciał wejść do sekcji krytycznej, co poskutkuje, że znów zostanie uśpiony. Następnie T1 zwolni blokadę i T2 może zostać ponownie obudzony. Co prawda, to nie jest zagrożenie z pokroju deadlock, ponieważ aplikacja będzie działać. W świecie wielowątkowym, chcemy jednak aby wszystko działało optymalnie. Z tego względu, nie możemy sobie pozwolić na niepotrzebne zmiany kontekstu, spowodowane przez wybudzenie i uśpienie po chwili jakiegoś wątku.

Z tego co wyczytałem, na jedno rdzeniowych procesorach to jest jeszcze gorzej. W momencie gdy wysyłamy sygnał za pomocą Set, Windows zwiększy priorytet T2 tak, że T2 na pewno wywłaszczy T1. Proszę zauważyć, że nie zawsze mamy wpływ na ten problem. Domyślna implementacja condition variables w CLR, spowoduje two-step dance:

public void Thread1()
{
  Monitor.Enter(_lock);

  while (!_condition)
  {
      Monitor.Wait(_lock);
  }
  _condition = false;
  Monitor.Exit(_lock);
}

public void Thread2()
{
  Monitor.Enter(_lock);

  _condition = true;

  Monitor.Pulse(_lock);

  Monitor.Exit(_lock);
}

Niestety, aby korzystać z Pulse, musimy być w sekcji krytycznej – taka jest po prostu implementacja CLR. Nie mamy na to wpływu. Mimo wszystko, powinniśmy analizować nasz kod na bieżącą i wyłapywać niepotrzebne zmiany kontekstu, spowodowane przez two-step dance.

Leave a Reply

Your email address will not be published.