> Что такое дедлоки? (PHP)
Уровень: junior · Роль: backend · Язык: PHP · Категория: Технические вопросы
Компании: vanta
Стек: PHP
> Пример ответа
Короткий ответ
Дедлок - это ситуация, когда два или более процесса/потока блокируют друг друга, ожидая ресурсы, которые удерживает другой участник. Никто не может продолжить выполнение, и система зависает. В PHP это чаще встречается при работе с БД, файловыми блокировками или очередями. Классические условия возникновения - взаимное исключение, удержание и ожидание, отсутствие вытеснения и циклическое ожидание.
Подробное объяснение
Дедлок возникает, когда выполняются четыре условия Коффмана одновременно:
- Взаимное исключение - ресурс может использоваться только одним процессом за раз.
- Удержание и ожидание - процесс держит ресурс и ждёт другой.
- Отсутствие вытеснения - ресурс нельзя принудительно забрать.
- Циклическое ожидание - цепочка процессов, где каждый ждёт ресурс, удерживаемый следующим.
В контексте PHP дедлоки чаще всего проявляются на уровне БД (InnoDB row locks), файловых блокировок (flock) или распределённых систем (Redis locks). PHP сам по себе однопоточный, но при работе с очередями или воркерами несколько процессов могут конкурировать за одни ресурсы.
На практике
Типичный сценарий в PHP - два скрипта обновляют таблицы в разном порядке:
- Скрипт A:
UPDATE users ...затемUPDATE orders ... - Скрипт B:
UPDATE orders ...затемUPDATE users ...
Если оба стартуют одновременно, A блокирует users, B блокирует orders, и оба ждут освобождения чужой блокировки. MySQL обнаружит дедлок через таймаут и откатит одну транзакцию, но в файловых блокировках PHP такого механизма нет - процесс зависнет навсегда.
Для предотвращения используют:
- фиксированный порядок доступа к ресурсам;
- таймауты на получение блокировок;
- retry-логику при ошибках дедлока;
- короткие транзакции.
Пример кода
PHP// Пример дедлока на файловых блокировках$fileA = fopen('/tmp/a.lock', 'c');$fileB = fopen('/tmp/b.lock', 'c');// Процесс 1flock($fileA, LOCK_EX);sleep(1); // имитация работыflock($fileB, LOCK_EX); // зависнет, если процесс 2 уже держит b.lock// Процесс 2 (в другом процессе)flock($fileB, LOCK_EX);sleep(1);flock($fileA, LOCK_EX); // зависнет, если процесс 1 уже держит a.lock
Правильный подход - всегда блокировать файлы в одном порядке:
PHP// Всегда сначала A, потом Bflock($fileA, LOCK_EX);flock($fileB, LOCK_EX);
Как отвечать на собеседовании
Начни с определения, затем перечисли четыре условия Коффмана. Приведи пример из реальной практики - лучше всего с транзакциями БД, так как это ближе к backend-роли. Упомяни, что MySQL сам детектит дедлоки и откатывает одну из транзакций, а вот с файловыми блокировками нужно быть осторожнее. Заверши способами предотвращения: единый порядок доступа, таймауты, короткие транзакции.
Что проверяет интервьюер
Интервьюер оценивает:
- понимание базовых концепций конкурентности;
- умение объяснить абстрактную проблему на конкретном примере;
- знание инструментов PHP для работы с блокировками;
- осознание разницы между дедлоком и обычной блокировкой;
- практические навыки предотвращения дедлоков.
Типичные ошибки
- Путать дедлок с обычным ожиданием блокировки - в дедлоке никто никогда не получит ресурс.
- Говорить, что PHP не может иметь дедлоки из-за однопоточности - это неверно, так как речь о процессах и БД.
- Не упоминать условия Коффмана - это базовый признак понимания темы.
- Предлагать только один способ решения, например "просто добавить таймаут" - этого недостаточно.
- Забывать, что MySQL сам разрешает дедлоки, а вот в файловой системе PHP такого механизма нет.
> Похожие задачи по PHP
Как изменить взаимодействие с внешним сервисом, чтобы избежать увеличения нагрузки из-за ретраев
Напишите функцию, которая асинхронно сделает fetch-запрос, распарсит ответ и вернет имя пользователя
Какие есть способы оптимизации тяжелых запросов к базе данных
Как устроен процесс деплоя и инфраструктура
> Похожие задачи по backend
Как изменить взаимодействие с внешним сервисом, чтобы избежать увеличения нагрузки из-за ретраев
Напишите функцию, которая асинхронно сделает fetch-запрос, распарсит ответ и вернет имя пользователя
Почему вы сменили PHP на Go, что было мотиватором
Какие есть способы оптимизации тяжелых запросов к базе данных
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью