Skip to content

Instantly share code, notes, and snippets.

@rusdevops
Last active April 18, 2018 10:10
Show Gist options
  • Save rusdevops/9aff450a97058482fb2e53acffc9d2cb to your computer and use it in GitHub Desktop.
Save rusdevops/9aff450a97058482fb2e53acffc9d2cb to your computer and use it in GitHub Desktop.

п.1 На защиту выносился код до специальной пометки:

https://github.com/rusdevops/request-handler/blob/master/include/request.hpp#L57

поэтому п.1, п.4 можно не рассматривать, но стоит сказать, что для согласованного вывода, поскольку используется несколько операторов вывода в одном потоке, то необходимо синхронизация. (к примеру https://github.com/rusdevops/request-handler/blob/master/include/request.hpp#L82)

п.2 Что касается trailing return type, большенство программистов используют его для выравнивания кода, с целью улучшения читабельности.

Пример:

auto foo() -> std::vector<int>
auto bar() -> int
std::vector<int> foo();
int bar();

п.3

Инкапсуляция - механизм языка, позволяющий ограничить доступ одних компонентов программы к другим. Принцип инкапсуляции заключается в том, что в классе или структуре можно указать уровень доступности для обращения к каждому из его членов из кода, расположенного вне этого класса или структуры. В частности, в сообществе С++ принято рассматривать инкапсуляцию без сокрытия как неполноценную.

В данном простом примере, где пользовательский код напрямую обращается к полю, неполноценную инкапсуляцию не стоит применять.

https://github.com/rusdevops/request-handler/blob/master/include/request.hpp#L92

Лучше было бы объявить тип с использованием struct, но согласно заданию использовался class.

п.4 В данном простом примере переменная counter относится к "фабричной" функции GetRequest, которая в свою очереь находится в глобальном пространстве имен (согласно заданию), соответственно counter аналогично находится в глобальном пространстве имен.

п.5 В конструкторе в цикле происходит создание потоков

https://github.com/rusdevops/request-handler/blob/master/include/threadpool.hpp#L120

в случае если не установить флаг завершения done

https://github.com/rusdevops/request-handler/blob/master/include/threadpool.hpp#L124 то при генерации исключения на n-итерации цикла (n > 0) в общем случае останется n-1 висячих потоков

п.6 Это реализация потокобезопасной очереди с мелкогранулярными блокировками, часто используется для оптимизации, особено при использование шаблона проектирования producer-consumer

п.7 Задание было понятным. Но было принято решение сделать модифицированное задание с целью оптимизации работоспособности для малоядерных процессоров.

  1. std::cout потокобезопасен и глобальный мьютекс в данном случае не нужен.

  2. trailing return type избыточен в данном коде. Он применяется в основном для шаблонов и лямбд.

  3. Открытые данные в запросе std::string message;, можно было устанавливать через конструктор. Нарушает инкапсуляцию.

  4. Счетчик можно было спрятать в класс запроса static unsigned counter = 0;

  5. ThreadPool::ThreadPool перехват исключения. Объект не будет создан нет необходимости модифифцировать внутреннее состояние.

  6. Код сильно переусложнен особенно очередь. Очень опасное использование двух мьютексов, которые могут браться подряд, например в методе empty,

при этом есть возможность взять tail_mutex из вне. Еще один щаг и получим дедлок.

  1. Думаю не совсем правильно понято задание. Требовалось на начальном этапе задавать количество потоков производителей и обработчиков.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment