Выбор ответа Senior GIL, потоки и процессы обновлено
Как избежать взаимной блокировки
Вопрос
Поток 1 берёт lock_a, затем lock_b. Поток 2 берёт lock_b, затем lock_a. Как надёжнее всего убрать риск deadlock?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Брать блокировки везде в одном порядке. Взаимная блокировка возникает, когда потоки держат по одному ресурсу и ждут чужой.
Варианты ответа
- Заменить
LockнаRLock, он допускает повторный захват - Добавить
time.sleep(0.1)между захватами - Брать блокировки везде в одном порядкеправильный ответ
- Увеличить число потоков, чтобы кто-то всегда шёл
Разбор
Взаимная блокировка возникает, когда потоки держат по одному ресурсу и ждут чужой. Единый порядок захвата делает цикл ожидания невозможным. RLock разрешает повторный захват тем же потоком, а не разными. sleep лишь меняет вероятность, а число потоков на причину не влияет. Ещё помогают таймауты acquire(timeout=...) и сокращение числа блокировок.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «GIL, потоки и процессы»
- Выбор между потоками, процессами и asyncio
- Найти риск взаимной блокировки
- Время работы пула с ограничением параллелизма
- Смоделировать потерю обновления
- Зачем в CPython GIL
- Lock против RLock
- fork в многопоточной программе
- Free-threaded CPython в 3.13 и 3.14