Sobes.tech
Back to questions
Junior — Middle
84

Объясните концепцию взаимной блокировки процессов и как она может возникнуть в многопоточной системе

Companies where asked
Samsung Research CenterSamsung Research Center
СБЕР АвтоСБЕР Авто
Baum
ARQA

Answer from AI

sobes.tech AI

Взаимная блокировка (deadlock) — это ситуация в многопоточной или многопроцессной системе, когда два или более процесса (или потока) находятся в состоянии ожидания ресурсов, занятых друг другом, и ни один из них не может продолжить работу.

Пример возникновения взаимной блокировки:

  • Поток A захватывает ресурс 1 и пытается получить ресурс 2.
  • Поток B захватывает ресурс 2 и пытается получить ресурс 1.

Оба потока ждут освобождения ресурса, который удерживает другой, и система «зависает».

Для возникновения deadlock обычно должны выполняться четыре условия одновременно:

  1. Взаимное исключение — ресурсы не могут быть разделены.
  2. Удержание и ожидание — процесс удерживает ресурс и ждет другой.
  3. Невозможность принудительного освобождения — ресурсы освобождаются только самим процессом.
  4. Циклическое ожидание — существует круг процессов, каждый из которых ждет ресурс, удерживаемый следующим.

В многопоточных системах deadlock часто возникает при неправильном порядке захвата мьютексов или других блокировок. Чтобы избежать взаимных блокировок, применяют:

  • Захват ресурсов в одном и том же порядке во всех потоках.
  • Использование таймаутов при ожидании блокировок.
  • Детектирование и восстановление из deadlock.

Пример на C++ с std::mutex:

std::mutex mtx1, mtx2;

void thread1() {
    std::lock_guard<std::mutex> lock1(mtx1);
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::lock_guard<std::mutex> lock2(mtx2);
    // работа с ресурсами
}

void thread2() {
    std::lock_guard<std::mutex> lock2(mtx2);
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::lock_guard<std::mutex> lock1(mtx1);
    // работа с ресурсами
}

Здесь возможна взаимная блокировка, если thread1 захватит mtx1, а thread2 — mtx2, и оба будут ждать друг друга.