Це залежить від того, як реалізуються блокування. Якщо ви зробите це так, як у статті Вікіпедії, тобто захищаєте критичний розділ одним булевим процесом¹, ви, звичайно, у біді. Якщо один процес гине, він ніколи не скидає свій прапор, тому інший процес зациклюється назавжди.
На практиці ви можете захистити свій код від багатьох способів вмирання. Наприклад, візьміть цю реалізацію в стилі Java:
flag[1] = true;
turn = 1;
while ( flag[0] == true && turn == 1 ) { Thread.yield(); }
try {
// critical section
}
finally {
flag[1] = false;
}
Це дозволить переконатися, що прапор скидається, що б не трапилось у критичному розділі, якщо система обробляє помилку. У Java це справедливо навіть для переповнення стека та купи. Тому, якщо процес буквально не зникає ( kill
², збій процесора, відключення мережі, ...), ви в безпеці. Зауважте, що більшість некритичних програм в цих випадках виходить з ладу - як можна обробити помилку, яку вона не працює? - так що це має бути прийнято у багатьох випадках. Ви можете усунути невідповідності при перезапуску, якщо це необхідно.
Якщо ви використовуєте правильні блокування на рівні мови, система виконання може обробляти зниклих власників замків, тобто звільняти блоки з мертвими власниками. Ви можете змоделювати це самостійно, надаючи кожному процесу перемикач мертвого чоловіка, який можуть прочитати інші, або перевірити безпосередньо, чи залишається процес володіння замком (якщо система його підтримує).
- Це все одно не добре.
- На Java, я думаю, це
finalize
має виконуватися навіть увімкнено kill
, але це не гарантується специфікацією. kill -9
це, мабуть, смертний вирок для будь-якого рішення, яке вимагає, щоб процес вмирання щось робив.