Zależy to od sposobu implementacji blokad. Jeśli zrobisz to tak, jak w artykule z Wikipedii, tj. Pilnujesz sekcji krytycznej jednym logicznym na proces¹, z pewnością masz kłopoty. Jeśli jeden proces umiera, nigdy nie resetuje flagi, więc drugi proces zapętla się na zawsze.
W praktyce możesz zabezpieczyć swój kod przed wieloma sposobami umierania. Na przykład weźmy tę implementację w stylu Java:
flag[1] = true;
turn = 1;
while ( flag[0] == true && turn == 1 ) { Thread.yield(); }
try {
// critical section
}
finally {
flag[1] = false;
}
Dzięki temu flaga zostanie zresetowana bez względu na to, co dzieje się w sekcji krytycznej, o ile system obsługuje błąd. W Javie jest tak nawet w przypadku przepełnienia stosu i sterty. Jeśli więc proces nie zniknie dosłownie ( kill
², awaria procesora, rozłączenie sieci, ...) jesteś bezpieczny. Zauważ, że większość niekrytycznych programów zawodzi w takich przypadkach - jak poradzić sobie z błędem, którego nie uruchamia? - w wielu przypadkach należy to zaakceptować. W razie potrzeby można obsługiwać niespójności po ponownym uruchomieniu.
Jeśli użyjesz odpowiednich blokad na poziomie języka, system wykonawczy może obsługiwać znikających właścicieli blokad, tj. Zwalniać blokady z martwymi właścicielami. Możesz to zasymulować samodzielnie, nadając każdemu procesowi przełącznik martwego człowieka, który inni mogą odczytać, lub sprawdź bezpośrednio, czy proces posiadania zamka jest nadal aktywny (jeśli system go obsługuje).
- To i tak nie jest dobrze skalowane.
- Myślę, że w Javie
finalize
powinien działać nawet na kill
, ale specyfikacja tego nie gwarantuje. kill -9
jest prawdopodobnie wyrokiem śmierci za każde rozwiązanie wymagające procesu umierania, aby coś zrobić.