Работа с Visual Studio.Net

         

Тупиковая ситуация (Deadlock)

Выше мы рассмотрели, как потоки одного процесса могут вступить в конфликт и испортить работу друг друга. Одной из задач программиста является обеспечить невозможность такого сценария. Другими возможными неприятностями могут быть: рассинхронизация (race conditions) и тупиковая ситуация (deadlock).

Первая может произойти, когда успех одной операции зависит от успеха другой, но обе они не синхронизированы друг с другом. Предположим, что один поток процесса подготавливает принтер, а другой ставит задание на печать (print job) в очередь. Если потоки не синхронизированы и первый из них не успеет выполнить свою работу до того, как начнется печать, то мы получим сбой.

Примечание

Но в каком-то количестве


случаев все пройдет гладко. Такой тип ошибок очень неприятен, так как в процессе отладки ее нельзя уверенно и многократно воспроизводить. Рассинхронизация порождает ненадежность —тип ошибок, который большинство программистов всего мира ненавидит. В MSDN, но, к сожалению, не в литературе, вы часто можете встретить упоминания о коварстве irreprodudble bugs (невоспроизводимые ошибки). Суверенностью можно сказать, что книга под названием «Технологии борьбы с ошибками» была бы бестселлером.

Тупиковая ситуация создается, когда один поток ждет завершения второго, а второй ждет завершения первого. Представьте, что один поток реализует такую функцию:

  • блокирует запись, идентифицирующую клиента;
  • блокирует запись, описывающую его счет;
  • изменяет обе записи;
  • освобождает запись, описывающую счет;
  • освобождает запись, идентифицирующую клиента.
Обратите внимание на то, что освобождение блокировок происходит в обратном порядке. Именно так следует поступать при работе с записями базы данных и всеми объектами ядра Windows. Предположим далее, что второй поток реализует функцию начисления месячного процента и он делает те же действия, что и первый, но порядок блокирования и освобождения записей обратный. Оба потока по отдельности функционируют вполне надежно. В процессе работы возможен следующий сценарий: первый поток блокирует запись, идентифицирующую клиента, затем второй блокирует запись, описывающую его счет. После этого оба ждут освобождения записей, блокированных друг другом. Если ожидание реализовано разработчиком в виде бесконечного цикла, то мы его получили. Это тупиковая ситуация, или deadlock.

Содержание раздела