Use unfinished tasks num instead of idle thread num (#45)

This commit is contained in:
antonio2368 2020-11-19 16:46:01 +01:00 committed by Antonio Andelic
parent 03cc568e39
commit 76f0d5873b
3 changed files with 10 additions and 8 deletions

View File

@ -11,6 +11,7 @@ ThreadPool::ThreadPool(const size_t pool_size) {
void ThreadPool::AddTask(std::function<void()> new_task) { void ThreadPool::AddTask(std::function<void()> new_task) {
task_queue_.WithLock([&](auto &queue) { task_queue_.WithLock([&](auto &queue) {
queue.emplace(std::make_unique<TaskSignature>(std::move(new_task))); queue.emplace(std::make_unique<TaskSignature>(std::move(new_task)));
unfinished_tasks_num_.fetch_add(1);
}); });
queue_cv_.notify_one(); queue_cv_.notify_one();
} }
@ -55,22 +56,23 @@ void ThreadPool::ThreadLoop() {
return; return;
} }
(*task)(); (*task)();
unfinished_tasks_num_.fetch_sub(1);
task = PopTask(); task = PopTask();
} }
std::unique_lock guard(pool_lock_); std::unique_lock guard(pool_lock_);
idle_thread_num_.fetch_add(1);
queue_cv_.wait(guard, [&] { queue_cv_.wait(guard, [&] {
task = PopTask(); task = PopTask();
return task || terminate_pool_.load(); return task || terminate_pool_.load();
}); });
idle_thread_num_.fetch_sub(1);
if (terminate_pool_.load()) { if (terminate_pool_.load()) {
return; return;
} }
} }
} }
size_t ThreadPool::IdleThreadNum() const { return idle_thread_num_.load(); } size_t ThreadPool::UnfinishedTasksNum() const {
return unfinished_tasks_num_.load();
}
} // namespace utils } // namespace utils

View File

@ -29,7 +29,7 @@ class ThreadPool {
ThreadPool &operator=(const ThreadPool &) = delete; ThreadPool &operator=(const ThreadPool &) = delete;
ThreadPool &operator=(ThreadPool &&) = delete; ThreadPool &operator=(ThreadPool &&) = delete;
size_t IdleThreadNum() const; size_t UnfinishedTasksNum() const;
private: private:
std::unique_ptr<TaskSignature> PopTask(); std::unique_ptr<TaskSignature> PopTask();
@ -38,7 +38,7 @@ class ThreadPool {
std::vector<std::thread> thread_pool_; std::vector<std::thread> thread_pool_;
std::atomic<size_t> idle_thread_num_{0}; std::atomic<size_t> unfinished_tasks_num_{0};
std::atomic<bool> terminate_pool_{false}; std::atomic<bool> terminate_pool_{false};
std::atomic<bool> stopped_{false}; std::atomic<bool> stopped_{false};
utils::Synchronized<std::queue<std::unique_ptr<TaskSignature>>, utils::Synchronized<std::queue<std::unique_ptr<TaskSignature>>,

View File

@ -9,8 +9,8 @@
using namespace std::chrono_literals; using namespace std::chrono_literals;
TEST(ThreadPool, Basic) { TEST(ThreadPool, Basic) {
constexpr size_t adder_count = 100'000; constexpr size_t adder_count =
constexpr std::array<size_t, 5> pool_sizes{1, 2, 4, 8, 100}; 500'000; constexpr std::array<size_t, 5> pool_sizes{1, 2, 4, 8, 100};
for (const auto pool_size : pool_sizes) { for (const auto pool_size : pool_sizes) {
utils::ThreadPool pool{pool_size}; utils::ThreadPool pool{pool_size};
@ -20,7 +20,7 @@ TEST(ThreadPool, Basic) {
pool.AddTask([&] { count.fetch_add(1); }); pool.AddTask([&] { count.fetch_add(1); });
} }
while (pool.IdleThreadNum() != pool_size) { while (pool.UnfinishedTasksNum() != 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }