#ifndef __CC_ThreadPool_H__ #define __CC_ThreadPool_H__ #pragma once #include "iostream" #include #include "deque" #include #include #include #include "CCThread.h" #include "CC.h" class CCThreadPool { public: struct TaskPool { bool Running = false; int ID = -1; bool Sign = false; bool Online = false; std::function TaskFun = nullptr; }; public: CCThreadPool() = default; explicit CCThreadPool(int numThreads); CCThreadPool(CCThreadPool& other); void InitStart(int corePoolSize); void InitStart(int corePoolSize, int maximumPoolSize,int keepAliveTime); template void AddTask(Func && func, Args&&... args); int GetThreadCount() const; int GetUnusedCount() const; int GetCorePoolSize() const; int GetPoolMaxSize() const; int GetTaskRunningSize() const; void SetPrint(bool F); void SetThreadTimeout(int us); void Stop(bool F = true); private: void worker(int ID); template void AdHocTasks(Func && func, Args&&... args); std::vector> m_taskQueue; std::map m_threads; std::mutex m_mutex; int m_corePoolSize = 5, m_maximumPoolSize = 30, m_keepAliveTime = 1000 * 1000 * 16; int TaskRunningSize = 0,TemporaryThreads = 0; bool Print = false; }; template inline void CCThreadPool::AddTask(Func && func, Args&&... args) { if(TaskRunningSize >= m_maximumPoolSize){ CC::Println("CCThreadPool::AddTask: Threaded tasks exceed the maximum, wait!"); return; } std::function FUNS = std::bind(std::forward(func), std::forward(args)...); if(FUNS){ m_mutex.lock(); CCVar Len = GetUnusedCount(); if(Len > 0){ for(auto &[fst, snd] : m_threads) { if(!snd.Running) { snd.TaskFun = FUNS; snd.Running = true; break; } } } else { AdHocTasks(FUNS); } m_mutex.unlock(); } else { CC::Println("CCThreadPool::AddTask: The task is empty!"); } } template inline void CCThreadPool::AdHocTasks(Func &&func, Args &&... args) { CCThread([this,func](){ TemporaryThreads++; try { func(); } catch (CCException& e) { String str = "CCThreadPool::AdHocTasks: The temporary task failed -> " + CC::to_String(e.what()); CC::Println(str); } TemporaryThreads--; CCThread::Sleep(m_keepAliveTime); }).detach(); } #endif