Дедлок (Deadlock) — это состояние, при котором два или более потока или процессов блокируются, ожидая друг друга, чтобы продолжить выполнение. Возникает, когда каждый поток владеет ресурсом, который нужен другому потоку, и сам ожидает освобождения ресурса, удерживаемого другим потоком.
Четыре условия, необходимые для возникновения дедлока (условия Коффмана):
- Взаимное исключение (Mutual Exclusion): Ресурс не может использоваться одновременно несколькими процессами.
- Удержание и ожидание (Hold and Wait): Поток, уже владеющий хотя бы одним ресурсом, ожидает получения дополнительных ресурсов, которые в данный момент заняты другими потоками.
- Отсутствие принудительного освобождения (No Preemption): Ресурсы не могут быть принудительно отняты у потока. Они могут быть освобождены только добровольно потоком, который ими владеет.
- Циклическое ожидание (Circular Wait): Существует цикл ожиданий между двумя или более потоками. Например, Поток A ожидает ресурс, удерживаемый Потоком B, который ожидает ресурс, удерживаемый Потоком C, который ожидает ресурс, удерживаемый Потоком A.
В iOS разработке дедлоки часто возникают при работе сConcurrency (многопоточностью), например, при неправильном использовании GCD (Grand Central Dispatch) или Operation Queues:
- Попытка синхронного выполнения блока кода на очереди, на которой уже находится текущий поток (например, вызов
sync на main очереди из главного потока).
- Два потока пытаются захватить два разных замка или семафора в разном порядке.
Пример простого дедлока с использованием GCD:
swift