Взаимная блокировка
Взаи́мная блокиро́вка (англ. deadlock) — ситуация в многозадачной среде или СУБД, при которой несколько процессов находятся в состоянии бесконечного ожидания ресурсов, захваченных самими этими процессами.
Простейший пример взаимной блокировки
Процесс 1 | Процесс 2 |
---|---|
Хочет захватить A и B, начинает с A | Хочет захватить A и B, начинает с B |
Захватывает ресурс A | |
Захватывает ресурс B | |
Ожидает освобождения ресурса A | |
Ожидает освобождения ресурса B | |
Взаимная блокировка |
Отладка взаимных блокировок, как и других ошибок синхронизации, усложняется тем, что для их возникновения нужны специфические условия одновременного выполнения нескольких процессов (в вышеописанном примере если бы процесс 1 успел захватить ресурс B до процесса 2, то ошибка не произошла бы).
Livelock
Это слово означает такую ситуацию: система не «застревает» (как в обычной взаимной блокировке), а занимается бесполезной работой, её состояние постоянно меняется — но, тем не менее, она «зациклилась», не производит никакой полезной работы.
Жизненный пример такой ситуации: двое встречаются лицом к лицу. Каждый из них пытается посторониться, и они не расходятся, а несколько секунд ходят влево-вправо.
Обнаружение взаимных блокировок
Поиск взаимных блокировок осуществляется путем построения и анализа графа ожидания. В графе ожидания узлами отмечаются процессы и объекты. Блокировки отмечаются рёбрами, направленными от узла, соответствующего захваченному объекту, к узлу, соответствующему захватившему его процессу. Ожидания отмечаются рёбрами, направленными от узла, соответствующего ожидающему процессу, к узлу, соответствующему ожидаемому объекту.
Цикл в графе ожидания соответствует взаимной блокировке. Существует специальный алгоритм поиска циклов в графе .
Существуют алгоритмы удаления взаимной блокировки. В то же время, выполнение алгоритмов поиска удаления взаимных блокировок может привести к livelock — взаимная блокировка образуется, сбрасывается, снова образуется, снова сбрасывается и так далее.
Кроме того, эти алгоритмы реализуются менеджером ресурсов — программой, отвечающей за блокировку и разблокировку. Если же часть занятых в блокировке ресурсов распределяется кем-то другим, обнаружение взаимной блокировки невозможно. К примеру, СУБД Oracle обнаруживает взаимную блокировку запросов к её базам данных, но если в приведенном примере объекты — это поле базы и, к примеру, файл на жестком диске, взаимная блокировка обнаружена не будет — СУБД этот файл не обрабатывает и для неё взаимной блокировки нет.
Практически об устранении взаимных блокировок надо заботиться ещё на этапе проектирования системы — это единственный более-менее надежный способ с ними бороться. В крайнем случае, когда основная концепция не допускает возможности избежать взаимных блокировок, следует хотя бы строить все запросы ресурсов так, чтобы такие блокировки безболезненно снимались.
Классический способ борьбы с проблемой — разработка иерархии блокировок, установление правила, что некоторые блокировки никогда не могут захватываться в состоянии, в котором уже захвачены какие-то другие блокировки. Говоря точно, речь о разработке отношения сравнения между блокировками, и о запрете захвата «большей» блокировки в состоянии, когда уже захвачена «меньшая».
В некоторых случаях, особенно в поделенных на модули архитектурах, это является проблемой. Так, например, в межмодульном интерфейсе приходится вводить вызовы, которые не делают ничего, кроме захвата и освобождения неких блокировок в модуле. Такой подход используется в файловых системах Windows в интерфейсе их взаимодействия с подсистемами кэша и виртуальной памяти.
В файловой системе существуют блокировки, «защищающие» переменные «размер файла» и «длина реально записанных данных в файле». В некоторых случаях возможно исполнение ввода/вывода на диск с удержанием этих блокировок.
Исполнение же ввода/вывода, в том числе построение запросов ввода/вывода, требует взятия блокировок низкого уровня уже в подсистеме виртуальной памяти, и следующий за этим вызов в файловую систему.
Для реализации этого паттерна файловая система предоставляет подсистеме виртуальной памяти вызовы, специально предназначенные для захвата блокировок.
Есть способы избежания данной проблемы:
1. Не бери ложку , если не положил вилку
2. Бери ложку и вилку сразу (WaitForMultipleObjects)
См. также
Ссылки
- Deadlock Detection Agents
- Paper «Deadlock Detection in Distributed Object Systems» by Nima Kaveh and Wolfgang Emmerich
- Article «Distributed Deadlock Detection» by JoAnne L. Holliday and Amr El Abbadi
- Article «Deadlock detection in distributed databases» by Edgar Knapp
- Article «Advanced Synchronization in Java Threads» by Scott Oaks and Henry Wong
- Paper «Confirmation of Deadlock Potentials Detected by Runtime Analysis» by Saddek Bensalem, Jean-Claude Fernandez, Klaus Havelund and Laurent Mounier
- Coffman, E.G., M.J. Elphick, and A. Shoshani, System Deadlocks, ACM Computing Surveys, 3, 2, 67-78 (1971).
- Paper Eliminating Receive Livelock in an Interrupt-driven Kernel by Jeffrey C. Mogul, K. K. Ramakrishnan
- DeadLock at the Portland Pattern Repository
- Etymology of «Deadlock»
- ARCS — A Web Service approach to alleviating deadlock
ca:Abraçada mortal cs:Deadlock de:Deadlock en:Deadlock es:Bloqueo mutuo fr:Interblocage he:קיפאון (מדעי המחשב) hu:Holtpont it:Deadlock ja:デッドロック ko:교착 상태 lt:Rakinimo aklavietė pl:Zakleszczenie pt:Deadlock simple:Deadlock sv:Baklås (datavetenskap) uk:Взаємне блокування vi:Deadlock zh:死锁
Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....