inlinestd::size_tdefault_thread_pool_size()noexcept{std::size_tnum_threads=std::thread::hardware_concurrency()*2;num_threads=num_threads==0?2:num_threads;returnnum_threads;}classThreadPool{private:std::mutexmutex_;std::condition_variablecv_;std::atomic<bool>stop_;std::atomic<std::size_t>num_threads_;std::queue<Task>tasks_;std::vector<std::thread>pool_;public:usingTask=std::packaged_task<void()>;ThreadPool(constThreadPool&)=delete;ThreadPool&operator=(constThreadPool&)=delete;ThreadPool(std::size_tnum_thread=default_thread_pool_size()):stop_{false},num_threads_{num_thread}{start();}~ThreadPool(){stop();}voidstop(){stop_.store(true);cv_.notify_all();for(auto&thread:pool_){if(thread.joinable()){thread.join();}}pool_.clear();}template<typenameF,typename...Args>std::future<std::invoke_result_t<std::decay_t<F>,std::decay_t<Args>...>>submit(F&&f,Args&&...args){usingRetType=std::invoke_result_t<std::decay_t<F>,std::decay_t<Args>...>;if(stop_.load()){throwstd::runtime_error("ThreadPool is stopped");}autotask=std::make_shared<std::packaged_task<RetType()>>(std::bind(std::forward<F>(f),std::forward<Args>(args)...));std::future<RetType>ret=task->get_future();{std::lock_guard<std::mutex>lc{mutex_};tasks_.emplace([task]{(*task)();});}cv_.notify_one();returnret;}voidstart(){for(std::size_ti=0;i<num_threads_;++i){pool_.emplace_back([this]{while(!stop_){Tasktask;{std::unique_lock<std::mutex>lc{mutex_};cv_.wait(lc,[this]{returnstop_||!tasks_.empty();});if(tasks_.empty())return;task=std::move(tasks_.front());tasks_.pop();}task();}});}}};