Ревью и улучшение функции обработки сообщений из общей очереди

Локальный mutex не защищает общую очередь между вызовами. Кроме того, код дважды unlock-ит мьютекс и использует ссылку на элемент после снятия защиты. Сообщение нужно извлечь под общей блокировкой.

Короткий ответ

Что ответить на собеседовании

Локальный mutex не защищает общую очередь между вызовами. Кроме того, код дважды unlock-ит мьютекс и использует ссылку на элемент после снятия защиты. Сообщение нужно извлечь под общей блокировкой.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо провести ревью функции handle_message, которая читает сообщения из глобальной очереди и передаёт их в длительный расчёт.

  1. Выявить логические ошибки и потенциальные состояния гонки.
  2. Предложить и реализовать рефакторинг кода.
  3. Особое внимание уделить корректному использованию мьютекса: правильному захвату, отпусканию и исключению двойного разблокирования.
std::queue<std::string> g_messages;

void long_calculation_with_message(const std::string& message);

void handle_message() {
    std::mutex mutex;
    mutex.lock();

    if (!g_messages.empty()) {
        const std::string& message = g_messages.front();
        mutex.unlock();

        long_calculation_with_message(message);

        mutex.lock();
        g_messages.pop();
        mutex.unlock();
    }

    mutex.unlock();
}

Ответ

Локальный mutex не защищает общую очередь между вызовами. Кроме того, код дважды unlock-ит мьютекс и использует ссылку на элемент после снятия защиты. Сообщение нужно извлечь под общей блокировкой.

Все производители и потребители должны использовать один mutex:

std::mutex g_messages_mutex;

void handle_message() {
    std::string message;
    {
        std::lock_guard<std::mutex> lock(g_messages_mutex);
        if (g_messages.empty()) return;
        message = std::move(g_messages.front());
        g_messages.pop();
    }
    long_calculation_with_message(message);
}

Длительная работа выполняется без блокировки очереди, а RAII исключает двойное освобождение. Если расчёт бросит исключение, сообщение уже извлечено: политика повторов или подтверждения обработки должна быть отдельной частью системы.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее