Безпечний стан безвісний, безумовно, але якщо ви не можете виконати всі вимоги щодо запобігання тупиковій ситуації, це може статися. Наприклад, якщо дві нитки можуть потрапити в глухий кут, коли вони починають нитку A, то нитка B, але коли вони починаються навпаки (B, A), вони працюватимуть нормально - дозвольте припустити, що B приємніше;) Стан системи небезпечний, але з вдалою початковою послідовністю вона буде працювати. Ніякого глухого кута, але це можливо. Якщо ви також синхронізуєте їх вручну - почніть в належному порядку - це небезпечно - чомусь вони не можуть бути звільнені так, як вам подобається - система все ще є небезпечною (через можливий глухий кут), але ймовірність цього є низькою. У разі деяких зовнішніх подій, таких як заморожування ниток або переривань після їх продовження, це не вдасться.
Ви повинні усвідомити - безпечний стан є достатньою умовою, щоб уникнути тупикової ситуації, але небезпечний - лише необхідний стан. Зараз важко написати код з голови, але я можу їх шукати. Я стикався з кодом в Ada, що більше 99/100 разів він прекрасно працював протягом декількох тижнів (а потім припинився через перезавантаження сервера, а не в глухий кут), але раз у той час він виходив з ладу через кілька секунд у стан тупику.
Дозвольте додати легкий приклад порівняння з поділом: Якщо ваша функція ділить c / d і повертає результат, не перевіряючи, чи d дорівнює 0, можливий поділ на нульову помилку, тому код небезпечний (призначене те саме іменування), але поки у вас такий поділ, все нормально, але після теоретичного аналізу код небезпечний і може потрапити в невизначену поведінку, якщо не обробляється належним чином.