Шаг 86 - Что такое смертельный захват(Deadlock) и как с ним бороться

Данная ситуация возникает при синхронизации нескольких потоков, но только в том случае если объектов синхронизации несколько. Давайте расмотрим ситуации когда два потока должны в ходе своей работы захватывать два ресурса монитор и клавиатуру. Только в том случае, когда оба эти ресурса захвачены поток может продолжаться.

86.gif (5074 b)

Такая ситуация когда два потока ждут друг друга и называется Deadlock. И это ожидание может продолжаться сколько угодно. Самое плохое, что эта ошибка может появляться редко. То есть появление данной ситуации нерегулярно, как сбой аппаратный. Это связано с квантованием времени. Давайте пример по шагам. Операционная система выделила время потоку 1 и тот сначала захватил монитор, а потом клавиатуру. Все нормально. Выделила время потоку 2. Тот сунулся, но не получилось - занято и замер в ожидании. Опять время первому потоку. Тот что-то сделал и освободил монитор. Потом опять второй. Он захватил монитор и ждет клавиатуру. Все работает нормально. Но вот если в первой ситуации за один квант времени поток не успел бы захватить два объекта, а только один эта ситуация и случилась бы. Как видите для ее реализации нужно, чтобы два потока в одно и то же время пытались захватить ресурсы. Кроме того кванта времени, который был выделен для потока должно не хватить для захвата всех ресурсов. Ситуация маловерояная, но все равно возможная. Исходя из того, что на ее появление влияет вероятность непредсказуемая. Выход осюда один. Если захват полностью не удался, то есть все необходимые ресурсы не захвачены надо освободить все и попробовать через некоторое время. К счастью нам не надо изобретать велосипед. Если нам необходимо захватить несколько объектов, то не надо использовать несколько WaitForSingleObject(), так как это прямой путь к Deadlock. Использование WaitForMultipleObject() снимает данную проблему при необходимости захвата нескольких ресурсов, так как если она ожидает несколько объектов, то пока она не захватит все, менять состояние отдельного она не будет. Поэтому организовав цикл запросов на захват многих объектов сразу Вы никогда не блокируете другой поток.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 6.05.2001