//! \~\file pithreadpoolloop.h //! \~\ingroup Thread //! \~\brief //! \~english Parallel loop helper //! \~russian Вспомогательный класс для параллельного цикла /* PIP - Platform Independent Primitives Thread pool loop Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PITHREADPOOLLOOP_H #define PITHREADPOOLLOOP_H #include "pisemaphore.h" #include "pivector.h" class PIThread; //! \~\ingroup Thread //! \~\brief //! \~english Helper that runs one integer range across a fixed set of worker threads. //! \~russian Вспомогательный класс, который выполняет один целочисленный диапазон на фиксированном наборе рабочих потоков. class PIP_EXPORT PIThreadPoolLoop { public: //! \~english Constructs parallel loop runner with \a thread_cnt worker threads. If \a thread_cnt is less than or equal to zero, the //! processor count is used. //! \~russian Создает исполнитель параллельного цикла с \a thread_cnt рабочими потоками. Если \a thread_cnt меньше либо равен нулю, //! используется количество процессоров. PIThreadPoolLoop(int thread_cnt = -1); //! \~english Stops worker threads and destroys the loop runner. //! \~russian Останавливает рабочие потоки и уничтожает исполнитель цикла. virtual ~PIThreadPoolLoop(); //! \~english Sets the iteration body called once for each index of a started range. //! \~russian Устанавливает тело итерации, которое вызывается один раз для каждого индекса запущенного диапазона. void setFunction(std::function f); //! \~english Waits for the current in-flight batch started by \a start(). //! \~russian Ожидает завершения текущего запущенного пакета, начатого через \a start(). void wait(); //! \~english Starts asynchronous execution for indices in range [\a index_start, \a index_start + \a index_count). //! \~russian Запускает асинхронное выполнение для индексов из диапазона [\a index_start, \a index_start + \a index_count). void start(int index_start, int index_count); //! \~english Runs the configured iteration body for indices in range [\a index_start, \a index_start + \a index_count) and waits for //! completion. //! \~russian Выполняет настроенное тело итерации для индексов из диапазона [\a index_start, \a index_start + \a index_count) и ожидает //! завершения. void exec(int index_start, int index_count); //! \~english Sets iteration body to \a f, runs it for indices in range [\a index_start, \a index_start + \a index_count), and waits for //! completion. //! \~russian Устанавливает тело итерации \a f, выполняет его для индексов из диапазона [\a index_start, \a index_start + \a //! index_count) и ожидает завершения. void exec(int index_start, int index_count, std::function f); private: PIVector threads; std::function func; PISemaphore sem_exec, sem_done; std::atomic_bool is_destroy = {false}; std::atomic_int counter = {0}, wait_count = {0}; }; #endif