Skip to content

BartolomeyKant/test_thread_pool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Задание

Мы предлагаем реализовать ThreadPool, который может исполнять любую работу в одном из заранее созданных рабочих потоков. И консольное приложение, которое демонстрирует работу ThreadPool. Если пользователь ввёл restart, то существующий ThreadPool уничтожается и создаётся новый с большим количеством рабочих потоков. Если пользователь ввёл exit, то приложение завершается. Если пользователь ввёл два числа, то приложение отправляет работу в ThreadPool по вычислению всех простых делителей первого числа (uint64), а второе число нужно для задания приоритета этой задаче. После завершения работы нужно вывести результат в консоль.

Мы хотим получить программу на современном C++, ведь в современном C++ есть потоки, примитивы синхронизации и много всего хорошего. Для сборки лучше всего использовать CMake. Ещё мы хотим получить текст, который описывает детали реализации.

Уверены, вы блестяще справитесь с заданием!

Сборка

Писалось все и тестилось на линуксе, но сам код, вроде как получился кросплатформенный. Перейти в каталог с проектом, создать папку build, сконфигурировать cmake.

cd test_thread_pool
mkdir build
cd build
cmake ..

После запустить сборку проекта.

make

Для теста

Для теста запустить исполняемый файл thrdpool_task, на экране отобразится приглашение к вводу.

> cd

Команды

Доступны следующие команды:

  • help - показать список команд
  • restart - перезапустить пул потоков, задачи в пуле будут уничтожены, при перезапуске, будет добавлен на один поток больше.
  • exit - завершение работы. Перед завершение программа дождется выполнения всех задач в очереди.
  • <N> <P> - число и приоритет. Будет добавлена задача по поиску списка простых делителей числа N. Если есть свободные потоки, то задача будет запущена немедленно, иначе задача будет сохранена в списке на ожидание с приоритетом P. Задачи с наибольшим приоритетом покидают список ожидания первыми.
  • ctrl+d - аналогично exit

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

239847298479287487 1
239847298449822834 2
23984733448729834 3
239847298475472934 4
213123 5
98987609808098111 6
230875890000000009 7
2398488888834 8
4729847545871123 9
213123 10

В процессе завершения задач на экране будет отображаться результат выполнения.

О проекте

При создании объекта ThreadPool создается набор потоков Thread. Если в качестве аргумента в конструктор ThreadPool передать число num, то будет создано num потоков, если num == 0, то количество потоков определяется функцией std::thread::hardware_concurrency().

Для хранения действий используется класс Action, для которого добавлены шаблонные реализации ActionImpl, имеющие разную реализацию в зависимости от типа возвращаемого значения у переданной функции. ActionImpl<R> воспринимает только функции R func() (func возвращает результат типа R и не принимает никаких аргументов).

Для добавления новых действий пользователем в классе ThreadPool есть шаблонные функции run_action, имеющие перегрузки для трех разных типов вызываемых объектов:

  • функция член класса
  • обычная функция
  • другой вызываемый объект, соответствующий std::is_invokable

Для приведения пользовательских функций к R func() используется std::bind.

run_action создает новый Action и возвращает пользователю объект ActionResult. Созданный Action запускается одним из свободных потоков, а если нет ни одного свободного потока, то сохраняется в списке для ожидания. ActionResult предоставляет пользователю функции для управления Action:

  • wait - блокирует текущий поток до завершения Action, если Action уже был выполнен, то управление в поток возвращается немедленно
  • res - возвращает результат выполнения функции в Action. Данная функция доступна только в реализациях с типом возвращаемого значения отличным от void
  • set_priority - задать приоритет Action

Для передачи функции на выполнение в поток используется класс Thread, который определяет непосредственно поток - std::thread и loop функцию для запуска Action в потоке. loop в бесконечном цикле ожидает появления нового Action. После добавления Action в Thread сохраненная функция запускается на выполнение. Для уведомления ThreadPool об завершении функции предусмотрен callback. Как только один из потоков освободился ThreadPool выбирает новый Action из сохраненных, с учетом заданного приоритета.

About

solution for test task of creation thread pool

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published