3
* @author Michael Fetisov (fetisov.michael@bmstu.ru)
8
* @copyright Copyright (c) 2022
10
* Модифицированная версия пула потоков из книги
11
* Anthony Williams. C++ Concurrency in Action. Second Edition
13
* Оптимизация работы (предотвращение нагрузки процессора) пока очередь пуста
14
* с использованием std::condition_variable.
18
#include "simodo/tp/ThreadPool.h"
19
#include "simodo/tp/WorkFunction.h"
25
ThreadPool::ThreadPool(int number_of_threads, bool start_immediately)
26
: _number_of_threads(number_of_threads)
27
, _necessary_to_stop(false)
29
if (_number_of_threads < 0)
30
_number_of_threads = std::thread::hardware_concurrency();
32
if (start_immediately)
36
ThreadPool::~ThreadPool()
41
void ThreadPool::submit(Task_interface * task)
43
if (_number_of_threads == 0) {
48
_task_queue.push(task);
49
_waiting_condition.notify_one();
53
void ThreadPool::submit(std::function<void()> function)
55
submit( new WorkFunction(function) );
58
void ThreadPool::start()
61
if (_number_of_threads == 0)
64
if (!_threads.empty())
67
_threads.reserve(_number_of_threads);
69
for(int i=0; i < _number_of_threads; ++i)
70
_threads.push_back(std::thread(&ThreadPool::worker,this));
72
_waiting_condition.notify_all();
75
_necessary_to_stop = true;
76
_waiting_condition.notify_all();
80
void ThreadPool::stop()
82
_necessary_to_stop = true;
83
_waiting_condition.notify_all();
85
for(size_t i=0; i < _threads.size(); ++i)
91
void ThreadPool::worker()
93
while(!_necessary_to_stop || !_task_queue.empty()) {
94
if (_task_queue.empty()) {
95
std::unique_lock<std::mutex> locker(_waiting_mutex);
96
_waiting_condition.wait(locker, [this]{ return !_task_queue.empty() || _necessary_to_stop; });
99
Task_interface * task = nullptr;
101
if(_task_queue.try_pop(task)) {